target-alpha improvements, version 4
cover target-alpha improvements, version 4
Changes from v3->v4:
* Use the standard implementation of load-locked/store-conditional. I think it's pretty gross, but probably better to be consistent with the other ports. And at least the port continues to build when the host compiler doesn't support __sync_bool_compare_and_swap.
* Return some value when reading the cycle counter.
* Properly sign-extend cvtlq.
Changes from v2->v3:
* Enable NPTL.
Changes from v1->v2:
* Use setcond and goto_tb.
r~
Richard Henderson (13):
target-alpha: Add flags markups to helpers.h.
target-alpha: Implement cpys{,n,e} inline.
target-alpha: Implement rs/rc properly.
target-alpha: Implement cvtql inline.
target-alpha: Implement cvtlq inline.
target-alpha: Use setcond for int comparisons.
target-alpha: Use non-inverted arguments to gen_{f}cmov.
target-alpha: Emit goto_tb opcodes.
target-alpha: Update commentary for opcode 0x1A.
target-alpha: Enable NPTL.
target-alpha: Indicate NORETURN status when raising exception.
target-alpha: Fix load-locked/store-conditional.
target-alpha: Implement RPCC.
configure | 1 + linux-user/main.c | 60 ++++ linux-user/syscall.c | 2 +- qemu-timer.h | 13 + target-alpha/cpu.h | 35 ++- target-alpha/helper.c | 7 +- target-alpha/helper.h | 179 +++++------ target-alpha/op_helper.c | 80 +----- target-alpha/translate.c | 802 ++++++++++++++++++++++++++++++---------------- 9 files changed, 713 insertions(+), 466 deletions(-)
PATCH 1/13 target-alpha: Add flags markups to helpers.h.
Almost all alpha helpers are at least TCG_CALL_CONST and a fair few are also TCG_CALL_PURE.
--- target-alpha/helper.h | 184 ++++++++++++++++++++++++------------------------ 1 files changed, 92 insertions(+), 92 deletions(-)
target-alpha/helper.h +92 -92
@@ -1,9 +1,9 @@#include "def-helper.h" DEF_HELPER_2(excp, void, int, int) -DEF_HELPER_0(load_pcc, i64) -DEF_HELPER_0(rc, i64) -DEF_HELPER_0(rs, i64) +DEF_HELPER_FLAGS_0(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64) +DEF_HELPER_FLAGS_0(rc, TCG_CALL_CONST, i64) +DEF_HELPER_FLAGS_0(rs, TCG_CALL_CONST, i64) DEF_HELPER_2(addqv, i64, i64, i64)DEF_HELPER_2 (addlv, i64, i64, i64)
@@ -11,98 +11,98 @@ DEF_HELPER_2(subqv, i64, i64, i64) DEF_HELPER_2(sublv, i64, i64, i64) DEF_HELPER_2(mullv, i64, i64, i64) DEF_HELPER_2(mulqv, i64, i64, i64) -DEF_HELPER_2(umulh, i64, i64, i64) - -DEF_HELPER_1(ctpop, i64, i64) -DEF_HELPER_1(ctlz, i64, i64) -DEF_HELPER_1(cttz, i64, i64) - -DEF_HELPER_2(zap, i64, i64, i64) -DEF_HELPER_2(zapnot, i64, i64, i64) - -DEF_HELPER_2(cmpbge, i64, i64, i64) - -DEF_HELPER_2(minub8, i64, i64, i64) -DEF_HELPER_2(minsb8, i64, i64, i64) -DEF_HELPER_2(minuw4, i64, i64, i64) -DEF_HELPER_2(minsw4, i64, i64, i64) -DEF_HELPER_2(maxub8, i64, i64, i64) -DEF_HELPER_2(maxsb8, i64, i64, i64) -DEF_HELPER_2(maxuw4, i64, i64, i64) -DEF_HELPER_2(maxsw4, i64, i64, i64) -DEF_HELPER_2(perr, i64, i64, i64) -DEF_HELPER_1(pklb, i64, i64) -DEF_HELPER_1(pkwb, i64, i64) -DEF_HELPER_1(unpkbl, i64, i64) -DEF_HELPER_1(unpkbw, i64, i64) - -DEF_HELPER_0(load_fpcr, i64) -DEF_HELPER_1(store_fpcr, void, i64) - -DEF_HELPER_1(f_to_memory, i32, i64) -DEF_HELPER_1(memory_to_f, i64, i32) -DEF_HELPER_2(addf, i64, i64, i64) -DEF_HELPER_2(subf, i64, i64, i64) -DEF_HELPER_2(mulf, i64, i64, i64) -DEF_HELPER_2(divf, i64, i64, i64) -DEF_HELPER_1(sqrtf, i64, i64) - -DEF_HELPER_1(g_to_memory, i64, i64) -DEF_HELPER_1(memory_to_g, i64, i64) -DEF_HELPER_2(addg, i64, i64, i64) -DEF_HELPER_2(subg, i64, i64, i64) -DEF_HELPER_2(mulg, i64, i64, i64) -DEF_HELPER_2(divg, i64, i64, i64) -DEF_HELPER_1(sqrtg, i64, i64) - -DEF_HELPER_1(s_to_memory, i32, i64) -DEF_HELPER_1(memory_to_s, i64, i32) -DEF_HELPER_2(adds, i64, i64, i64) -DEF_HELPER_2(subs, i64, i64, i64) -DEF_HELPER_2(muls, i64, i64, i64) -DEF_HELPER_2(divs, i64, i64, i64) -DEF_HELPER_1(sqrts, i64, i64) - -DEF_HELPER_2(addt, i64, i64, i64) -DEF_HELPER_2(subt, i64, i64, i64) -DEF_HELPER_2(mult, i64, i64, i64) -DEF_HELPER_2(divt, i64, i64, i64) -DEF_HELPER_1(sqrtt, i64, i64) - -DEF_HELPER_2(cmptun, i64, i64, i64) -DEF_HELPER_2(cmpteq, i64, i64, i64) -DEF_HELPER_2(cmptle, i64, i64, i64) -DEF_HELPER_2(cmptlt, i64, i64, i64) -DEF_HELPER_2(cmpgeq, i64, i64, i64) -DEF_HELPER_2(cmpgle, i64, i64, i64) -DEF_HELPER_2(cmpglt, i64, i64, i64) - -DEF_HELPER_2(cpys, i64, i64, i64) -DEF_HELPER_2(cpysn, i64, i64, i64) -DEF_HELPER_2(cpyse, i64, i64, i64) - -DEF_HELPER_1(cvtts, i64, i64) -DEF_HELPER_1(cvtst, i64, i64) -DEF_HELPER_1(cvtqs, i64, i64) -DEF_HELPER_1(cvtqt, i64, i64) -DEF_HELPER_1(cvtqf, i64, i64) -DEF_HELPER_1(cvtgf, i64, i64) -DEF_HELPER_1(cvtgq, i64, i64) -DEF_HELPER_1(cvtqg, i64, i64) -DEF_HELPER_1(cvtlq, i64, i64) - -DEF_HELPER_1(cvttq, i64, i64) -DEF_HELPER_1(cvttq_c, i64, i64) -DEF_HELPER_1(cvttq_svic, i64, i64) - -DEF_HELPER_1(cvtql, i64, i64) +DEF_HELPER_FLAGS_2(umulh, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) + +DEF_HELPER_FLAGS_1(ctpop, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(ctlz, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(cttz, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) + +DEF_HELPER_FLAGS_2(zap, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(zapnot, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(cmpbge, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(minub8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(minsb8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(minuw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(minsw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(maxub8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(maxsb8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(maxuw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(maxsw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(perr, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_1(pklb, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(pkwb, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(unpkbl, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(unpkbw, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) + +DEF_HELPER_FLAGS_0(load_fpcr, TCG_CALL_CONST | TCG_CALL_PURE, i64) +DEF_HELPER_FLAGS_1(store_fpcr, TCG_CALL_CONST, void, i64) + +DEF_HELPER_FLAGS_1(f_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i32, i64) +DEF_HELPER_FLAGS_1(memory_to_f, TCG_CALL_CONST | TCG_CALL_PURE, i64, i32) +DEF_HELPER_FLAGS_2(addf, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(subf, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(mulf, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(divf, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_1(sqrtf, TCG_CALL_CONST, i64, i64) + +DEF_HELPER_FLAGS_1(g_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(memory_to_g, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_2(addg, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(subg, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(mulg, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(divg, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_1(sqrtg, TCG_CALL_CONST, i64, i64) + +DEF_HELPER_FLAGS_1(s_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i32, i64) +DEF_HELPER_FLAGS_1(memory_to_s, TCG_CALL_CONST | TCG_CALL_PURE, i64, i32) +DEF_HELPER_FLAGS_2(adds, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(subs, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(muls, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(divs, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_1(sqrts, TCG_CALL_CONST, i64, i64) + +DEF_HELPER_FLAGS_2(addt, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(subt, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(mult, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(divt, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_1(sqrtt, TCG_CALL_CONST, i64, i64) + +DEF_HELPER_FLAGS_2(cmptun, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmpteq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmptle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmptlt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmpgeq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmpgle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmpglt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(cpys, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cpysn, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cpyse, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) + +DEF_HELPER_FLAGS_1(cvtts, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtst, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtqs, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtqt, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtqf, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtgf, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtgq, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtqg, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtlq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) + +DEF_HELPER_FLAGS_1(cvttq, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvttq_c, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvttq_svic, TCG_CALL_CONST, i64, i64) + +DEF_HELPER_FLAGS_1(cvtql, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) DEF_HELPER_1(cvtql_v, i64, i64) DEF_HELPER_1(cvtql_sv, i64, i64) -DEF_HELPER_1(setroundmode, void, i32) -DEF_HELPER_1(setflushzero, void, i32) -DEF_HELPER_0(fp_exc_clear, void) -DEF_HELPER_0(fp_exc_get, i32) +DEF_HELPER_FLAGS_1(setroundmode, TCG_CALL_CONST, void, i32) +DEF_HELPER_FLAGS_1(setflushzero, TCG_CALL_CONST, void, i32) +DEF_HELPER_FLAGS_0(fp_exc_clear, TCG_CALL_CONST, void) +DEF_HELPER_FLAGS_0(fp_exc_get, TCG_CALL_CONST | TCG_CALL_PURE, i32) DEF_HELPER_2(fp_exc_raise, void, i32, i32)DEF_HELPER_2 (fp_exc_raise_s, void, i32, i32)
Signature · 1 line
1.6.6.1
Aurelien Jarno
AppliedRe: [Qemu-devel] [PATCH 01/13] target-alpha: Add flags markups to helpers.h.
Quoted 2 lines · Richard Henderson
Almost all alpha helpers are at least
TCG_CALL_CONSTand a fair few are alsoTCG_CALL_PURE.
Thanks, applied.
Quoted 216 lines
Signed-off-by Richard Henderson <[email protected]>--- target-alpha/helper.h | 184 ++++++++++++++++++++++++------------------------ 1 files changed, 92 insertions(+), 92 deletions(-)target-alpha/helper.h +92
-92@@ -1,9 +1,9 @@#include "def-helper.h" DEF_HELPER_2(excp, void, int, int) -DEF_HELPER_0(load_pcc, i64) -DEF_HELPER_0(rc, i64) -DEF_HELPER_0(rs, i64) +DEF_HELPER_FLAGS_0(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64) +DEF_HELPER_FLAGS_0(rc, TCG_CALL_CONST, i64) +DEF_HELPER_FLAGS_0(rs, TCG_CALL_CONST, i64) DEF_HELPER_2(addqv, i64, i64, i64)DEF_HELPER_2 (addlv, i64, i64, i64)@@ -11,98 +11,98 @@ DEF_HELPER_2(subqv, i64, i64, i64) DEF_HELPER_2(sublv, i64, i64, i64) DEF_HELPER_2(mullv, i64, i64, i64) DEF_HELPER_2(mulqv, i64, i64, i64) -DEF_HELPER_2(umulh, i64, i64, i64) - -DEF_HELPER_1(ctpop, i64, i64) -DEF_HELPER_1(ctlz, i64, i64) -DEF_HELPER_1(cttz, i64, i64) - -DEF_HELPER_2(zap, i64, i64, i64) -DEF_HELPER_2(zapnot, i64, i64, i64) - -DEF_HELPER_2(cmpbge, i64, i64, i64) - -DEF_HELPER_2(minub8, i64, i64, i64) -DEF_HELPER_2(minsb8, i64, i64, i64) -DEF_HELPER_2(minuw4, i64, i64, i64) -DEF_HELPER_2(minsw4, i64, i64, i64) -DEF_HELPER_2(maxub8, i64, i64, i64) -DEF_HELPER_2(maxsb8, i64, i64, i64) -DEF_HELPER_2(maxuw4, i64, i64, i64) -DEF_HELPER_2(maxsw4, i64, i64, i64) -DEF_HELPER_2(perr, i64, i64, i64) -DEF_HELPER_1(pklb, i64, i64) -DEF_HELPER_1(pkwb, i64, i64) -DEF_HELPER_1(unpkbl, i64, i64) -DEF_HELPER_1(unpkbw, i64, i64) - -DEF_HELPER_0(load_fpcr, i64) -DEF_HELPER_1(store_fpcr, void, i64) - -DEF_HELPER_1(f_to_memory, i32, i64) -DEF_HELPER_1(memory_to_f, i64, i32) -DEF_HELPER_2(addf, i64, i64, i64) -DEF_HELPER_2(subf, i64, i64, i64) -DEF_HELPER_2(mulf, i64, i64, i64) -DEF_HELPER_2(divf, i64, i64, i64) -DEF_HELPER_1(sqrtf, i64, i64) - -DEF_HELPER_1(g_to_memory, i64, i64) -DEF_HELPER_1(memory_to_g, i64, i64) -DEF_HELPER_2(addg, i64, i64, i64) -DEF_HELPER_2(subg, i64, i64, i64) -DEF_HELPER_2(mulg, i64, i64, i64) -DEF_HELPER_2(divg, i64, i64, i64) -DEF_HELPER_1(sqrtg, i64, i64) - -DEF_HELPER_1(s_to_memory, i32, i64) -DEF_HELPER_1(memory_to_s, i64, i32) -DEF_HELPER_2(adds, i64, i64, i64) -DEF_HELPER_2(subs, i64, i64, i64) -DEF_HELPER_2(muls, i64, i64, i64) -DEF_HELPER_2(divs, i64, i64, i64) -DEF_HELPER_1(sqrts, i64, i64) - -DEF_HELPER_2(addt, i64, i64, i64) -DEF_HELPER_2(subt, i64, i64, i64) -DEF_HELPER_2(mult, i64, i64, i64) -DEF_HELPER_2(divt, i64, i64, i64) -DEF_HELPER_1(sqrtt, i64, i64) - -DEF_HELPER_2(cmptun, i64, i64, i64) -DEF_HELPER_2(cmpteq, i64, i64, i64) -DEF_HELPER_2(cmptle, i64, i64, i64) -DEF_HELPER_2(cmptlt, i64, i64, i64) -DEF_HELPER_2(cmpgeq, i64, i64, i64) -DEF_HELPER_2(cmpgle, i64, i64, i64) -DEF_HELPER_2(cmpglt, i64, i64, i64) - -DEF_HELPER_2(cpys, i64, i64, i64) -DEF_HELPER_2(cpysn, i64, i64, i64) -DEF_HELPER_2(cpyse, i64, i64, i64) - -DEF_HELPER_1(cvtts, i64, i64) -DEF_HELPER_1(cvtst, i64, i64) -DEF_HELPER_1(cvtqs, i64, i64) -DEF_HELPER_1(cvtqt, i64, i64) -DEF_HELPER_1(cvtqf, i64, i64) -DEF_HELPER_1(cvtgf, i64, i64) -DEF_HELPER_1(cvtgq, i64, i64) -DEF_HELPER_1(cvtqg, i64, i64) -DEF_HELPER_1(cvtlq, i64, i64) - -DEF_HELPER_1(cvttq, i64, i64) -DEF_HELPER_1(cvttq_c, i64, i64) -DEF_HELPER_1(cvttq_svic, i64, i64) - -DEF_HELPER_1(cvtql, i64, i64) +DEF_HELPER_FLAGS_2(umulh, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) + +DEF_HELPER_FLAGS_1(ctpop, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(ctlz, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(cttz, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) + +DEF_HELPER_FLAGS_2(zap, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(zapnot, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(cmpbge, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(minub8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(minsb8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(minuw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(minsw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(maxub8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(maxsb8, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(maxuw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(maxsw4, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(perr, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_1(pklb, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(pkwb, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(unpkbl, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(unpkbw, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) + +DEF_HELPER_FLAGS_0(load_fpcr, TCG_CALL_CONST | TCG_CALL_PURE, i64) +DEF_HELPER_FLAGS_1(store_fpcr, TCG_CALL_CONST, void, i64) + +DEF_HELPER_FLAGS_1(f_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i32, i64) +DEF_HELPER_FLAGS_1(memory_to_f, TCG_CALL_CONST | TCG_CALL_PURE, i64, i32) +DEF_HELPER_FLAGS_2(addf, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(subf, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(mulf, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(divf, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_1(sqrtf, TCG_CALL_CONST, i64, i64) + +DEF_HELPER_FLAGS_1(g_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_1(memory_to_g, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) +DEF_HELPER_FLAGS_2(addg, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(subg, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(mulg, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(divg, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_1(sqrtg, TCG_CALL_CONST, i64, i64) + +DEF_HELPER_FLAGS_1(s_to_memory, TCG_CALL_CONST | TCG_CALL_PURE, i32, i64) +DEF_HELPER_FLAGS_1(memory_to_s, TCG_CALL_CONST | TCG_CALL_PURE, i64, i32) +DEF_HELPER_FLAGS_2(adds, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(subs, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(muls, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(divs, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_1(sqrts, TCG_CALL_CONST, i64, i64) + +DEF_HELPER_FLAGS_2(addt, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(subt, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(mult, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_2(divt, TCG_CALL_CONST, i64, i64, i64) +DEF_HELPER_FLAGS_1(sqrtt, TCG_CALL_CONST, i64, i64) + +DEF_HELPER_FLAGS_2(cmptun, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmpteq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmptle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmptlt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmpgeq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmpgle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cmpglt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) + +DEF_HELPER_FLAGS_2(cpys, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cpysn, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) +DEF_HELPER_FLAGS_2(cpyse, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) + +DEF_HELPER_FLAGS_1(cvtts, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtst, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtqs, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtqt, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtqf, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtgf, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtgq, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtqg, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvtlq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) + +DEF_HELPER_FLAGS_1(cvttq, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvttq_c, TCG_CALL_CONST, i64, i64) +DEF_HELPER_FLAGS_1(cvttq_svic, TCG_CALL_CONST, i64, i64) + +DEF_HELPER_FLAGS_1(cvtql, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) DEF_HELPER_1(cvtql_v, i64, i64) DEF_HELPER_1(cvtql_sv, i64, i64) -DEF_HELPER_1(setroundmode, void, i32) -DEF_HELPER_1(setflushzero, void, i32) -DEF_HELPER_0(fp_exc_clear, void) -DEF_HELPER_0(fp_exc_get, i32) +DEF_HELPER_FLAGS_1(setroundmode, TCG_CALL_CONST, void, i32) +DEF_HELPER_FLAGS_1(setflushzero, TCG_CALL_CONST, void, i32) +DEF_HELPER_FLAGS_0(fp_exc_clear, TCG_CALL_CONST, void) +DEF_HELPER_FLAGS_0(fp_exc_get, TCG_CALL_CONST | TCG_CALL_PURE, i32) DEF_HELPER_2(fp_exc_raise, void, i32, i32)DEF_HELPER_2 (fp_exc_raise_s, void, i32, i32)Signature · 1 line
1.6.6.1
Signature · 2 lines
Aurelien Jarno GPG: 1024D/F1BCDB73 [email protected] http://www.aurel32.net
PATCH 2/13 target-alpha: Implement cpys{, n, e} inline.
In reply to Richard Henderson--- target-alpha/helper.h | 4 -- target-alpha/op_helper.c | 18 ---------- target-alpha/translate.c | 78 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 26 deletions(-)
target-alpha/helper.h +0 -4
@@ -77,10 +77,6 @@ DEF_HELPER_FLAGS_2(cmpgeq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) DEF_HELPER_FLAGS_2(cmpgle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) DEF_HELPER_FLAGS_2(cmpglt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) -DEF_HELPER_FLAGS_2(cpys, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) -DEF_HELPER_FLAGS_2(cpysn, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) -DEF_HELPER_FLAGS_2(cpyse, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) - DEF_HELPER_FLAGS_1(cvtts, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvtst, TCG_CALL_CONST, i64, i64)DEF_HELPER_FLAGS_1 (cvtqs,TCG_CALL_CONST , i64, i64)
target-alpha/op_helper.c +0 -18
@@ -921,24 +921,6 @@ uint64_t helper_sqrtt (uint64_t a)return float64_to_t (fr); } - -/* Sign copy */ -uint64_t helper_cpys (uint64_t a,uint64_t b) -{ -return (a &0x8000000000000000ULL ) | (b & ~0x8000000000000000ULL ); -} - -uint64_t helper_cpysn (uint64_t a,uint64_t b) -{ -return ((~a) &0x8000000000000000ULL ) | (b & ~0x8000000000000000ULL ); -} - -uint64_t helper_cpyse (uint64_t a,uint64_t b) -{ -return (a &0xFFF0000000000000ULL ) | (b & ~0xFFF0000000000000ULL ); -} - -/* Comparisons */ uint64_t helper_cmptun (uint64_t a,uint64_t b) {
target-alpha/translate.c +74 -4
90 lines not on this page · raw message
Signature · 1 line
1.6.6.1
Re: [Qemu-devel] [PATCH 02/13] target-alpha: Implement cpys{, n, e} inline.
Quoted 74 lines · Richard Henderson
Signed-off-by Richard Henderson <[email protected]>--- target-alpha/helper.h | 4 -- target-alpha/op_helper.c | 18 ---------- target-alpha/translate.c | 78 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 74 insertions(+), 26 deletions(-)target-alpha/helper.h +0
-4@@ -77,10 +77,6 @@ DEF_HELPER_FLAGS_2(cmpgeq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) DEF_HELPER_FLAGS_2(cmpgle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) DEF_HELPER_FLAGS_2(cmpglt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) -DEF_HELPER_FLAGS_2(cpys, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) -DEF_HELPER_FLAGS_2(cpysn, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) -DEF_HELPER_FLAGS_2(cpyse, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) - DEF_HELPER_FLAGS_1(cvtts, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvtst, TCG_CALL_CONST, i64, i64)DEF_HELPER_FLAGS_1 (cvtqs,TCG_CALL_CONST , i64, i64)target-alpha/op_helper.c +0
-18@@ -921,24 +921,6 @@ uint64_t helper_sqrtt (uint64_t a)return float64_to_t (fr); } - -/* Sign copy */ -uint64_t helper_cpys (uint64_t a,uint64_t b) -{ -return (a &0x8000000000000000ULL ) | (b & ~0x8000000000000000ULL ); -} - -uint64_t helper_cpysn (uint64_t a,uint64_t b) -{ -return ((~a) &0x8000000000000000ULL ) | (b & ~0x8000000000000000ULL ); -} - -uint64_t helper_cpyse (uint64_t a,uint64_t b) -{ -return (a &0xFFF0000000000000ULL ) | (b & ~0xFFF0000000000000ULL ); -} - -/* Comparisons */ uint64_t helper_cmptun (uint64_t a,uint64_t b) {target-alpha/translate.c +15
-0@@ -741,6 +741,80 @@ static inline void glue(gen_f, name)(DisasContext *ctx, \IEEE_INTCVT (cvtqs)IEEE_INTCVT (cvtqt) +static void gen_cpys_internal(int ra, int rb, int rc, int inv_a, uint64_t mask) +{ + TCGv va, vb, vmask; +int za =0 , zb =0 ; + + if (unlikely(rc == 31)) { +return ; + } + + vmask =tcg_const_i64 (mask); + +TCGV_UNUSED_I64 (va); +if (ra ==31 ) { +if (inv_a) { + va = vmask;
target-alpha/translate.c static inline void glue(gen_f, name)(DisasContext *ctx, \ · line 768
Quoted 10 lines
target-alpha/translate.c +10
-0+ }else { + za =1 ; + } + }else { + va =tcg_temp_new_i64 (); +tcg_gen_mov_i64 (va, cpu_fir[ra]); +if (inv_a) { +tcg_gen_not_i64 (va, va); + } +tcg_gen_and_i64 (va, va, vmask);
You can use instead:
if (inv_a) {
tcg_gen_andc_i64(va, vmask, va);
} else {
tcg_gen_and_i64(va, vmask, va);
}Quoted 14 lines
target-alpha/translate.c +14
-0+ } + +TCGV_UNUSED_I64 (vb); +if (rb ==31 ) { + zb =1 ; + }else { + vb =tcg_temp_new_i64 (); +tcg_gen_andc_i64 (vb, cpu_fir[rb], vmask); + } + +switch (za *2 + zb) { +case 0 : +tcg_gen_or_i64 (cpu_fir[rc], va, vb); +break ;
target-alpha/translate.c static inline void glue(gen_f, name)(DisasContext *ctx, \ · line 792
Quoted 10 lines
target-alpha/translate.c +10
-0+case 1 : +tcg_gen_mov_i64 (cpu_fir[rc], va); +break ; +case 2 : +tcg_gen_mov_i64 (cpu_fir[rc], vb); +break ; +case 3 : +tcg_gen_movi_i64 (cpu_fir[rc],0 ); +break ; + }
It's probably more clear here if you use switch(za << 1 | zb) and later case 0 | 0:, case 0 | 1:, case 2 | 0 and case 2 | 1:.
Quoted 44 lines
target-alpha/translate.c +24
-4+tcg_temp_free (vmask); +if (ra !=31 ) { +tcg_temp_free (va); + } +if (rb !=31 ) { +tcg_temp_free (vb); + } +} + +static inline void gen_fcpys (int ra,int rb,int rc) +{ +gen_cpys_internal (ra, rb, rc,0 ,0x8000000000000000ULL ); +} + +static inline void gen_fcpysn (int ra,int rb,int rc) +{ +gen_cpys_internal (ra, rb, rc,1 ,0x8000000000000000ULL ); +} + +static inline void gen_fcpyse (int ra,int rb,int rc) +{ +gen_cpys_internal (ra, rb, rc,0 ,0xFFF0000000000000ULL ); +} +#define FARITH3 (name) \ static inline void glue(gen_f, name)(int ra, int rb, int rc) \ { \@@ -769,10 +843,6 @@ static inline void glue(gen_f, name)(int ra, int rb, int rc) \tcg_temp_free (vb); \ } \ } -/* ??? Ought to expand these inline; simple masking operations. */ -FARITH3(cpys) -FARITH3(cpysn) -FARITH3(cpyse)/* ??? VAX instruction qualifiers ignored. */ FARITH3 (addf)Signature · 1 line
1.6.6.1
Signature · 2 lines
Aurelien Jarno GPG: 1024D/F1BCDB73 [email protected] http://www.aurel32.net
PATCH 3/13 target-alpha: Implement rs/rc properly.
In reply to Richard HendersonThis is a per-cpu flag; there's no need for a spinlock of any kind.
We were also failing to manipulate the flag with $31 as a target reg and failing to clear the flag on execution of a return-from-interrupt instruction.
--- linux-user/main.c | 5 +++++ target-alpha/helper.h | 2 -- target-alpha/op_helper.c | 28 ++-------------------------- target-alpha/translate.c | 19 +++++++++++++++---- 4 files changed, 22 insertions(+), 32 deletions(-)
linux-user/main.c +5 -0
@@ -2357,6 +2357,11 @@ void cpu_loop (CPUState *env)while (1 ) { trapnr =cpu_alpha_exec (env); +/* All of the traps imply a transition through PALcode, which +implies an REI instruction has been executed. Which means +that the intr_flag should be cleared. */ + env->intr_flag =0 ; +switch (trapnr) {case EXCP_RESET :fprintf (stderr,"Reset requested. Exit\n" );
target-alpha/helper.h +0 -2
@@ -2,8 +2,6 @@ DEF_HELPER_2(excp, void, int, int) DEF_HELPER_FLAGS_0(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64) -DEF_HELPER_FLAGS_0(rc, TCG_CALL_CONST, i64) -DEF_HELPER_FLAGS_0(rs, TCG_CALL_CONST, i64) DEF_HELPER_2(addqv, i64, i64, i64)DEF_HELPER_2 (addlv, i64, i64, i64)
target-alpha/op_helper.c +2 -26
@@ -47,32 +47,6 @@ void helper_store_fpcr (uint64_t val)cpu_alpha_store_fpcr (env, val); } -static spinlock_t intr_cpu_lock =SPIN_LOCK_UNLOCKED ; - -uint64_t helper_rs (void ) -{ -uint64_t tmp; - -spin_lock (&intr_cpu_lock); - tmp = env->intr_flag; - env->intr_flag =1 ; -spin_unlock (&intr_cpu_lock); - -return tmp; -} - -uint64_t helper_rc (void ) -{ -uint64_t tmp; - -spin_lock (&intr_cpu_lock); - tmp = env->intr_flag; - env->intr_flag =0 ; -spin_unlock (&intr_cpu_lock); - -return tmp; -} -uint64_t helper_addqv (uint64_t op1,uint64_t op2) {uint64_t tmp = op1;
@@ -1211,6 +1185,7 @@ void helper_hw_rei (void) { env->pc = env->ipr[IPR_EXC_ADDR ] & ~3 ; env->ipr[IPR_EXC_ADDR ] = env->ipr[IPR_EXC_ADDR ] &1 ; + env->intr_flag =0 ;/* XXX: re-enable interrupts and memory mapping */ }
@@ -1218,6 +1193,7 @@ void helper_hw_ret (uint64_t a) { env->pc = a & ~3 ; env->ipr[IPR_EXC_ADDR ] = a &1 ; + env->intr_flag =0 ;/* XXX: re-enable interrupts and memory mapping */ }
target-alpha/translate.c +15 -4
@@ -1266,6 +1266,19 @@ static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit,gen_set_label (l2); } +static void gen_rx (int ra,int set) +{ +TCGv_i32 tmp; + +if (ra !=31 ) { +tcg_gen_ld8u_i64 (cpu_ir[ra], cpu_env, offsetof(CPUState , intr_flag)); + } + + tmp =tcg_const_i32 (set); +tcg_gen_st8_i32 (tmp, cpu_env, offsetof(CPUState , intr_flag)); +tcg_temp_free_i32 (tmp); +} +static inline int translate_one (DisasContext *ctx,uint32_t insn) {uint32_t palcode;
@@ -2359,16 +2372,14 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0xE000 :/* RC */ -if (ra !=31 ) -gen_helper_rc (cpu_ir[ra]); +gen_rx (ra,0 );break ;case 0xE800 :/* ECB */ break ;case 0xF000 :/* RS */ -if (ra !=31 ) -gen_helper_rs (cpu_ir[ra]); +gen_rx (ra,1 );break ;case 0xF800 :/* WH64 */
Signature · 1 line
1.6.6.1
Re: [Qemu-devel] [PATCH 03/13] target-alpha: Implement rs/rc properly.
Quoted 19 lines · Richard Henderson
This is a per-cpu flag; there's no need for a spinlock of any kind.
We were also failing to manipulate the flag with $31 as a target reg and failing to clear the flag on execution of a return-from-interrupt instruction.
Signed-off-by Richard Henderson <[email protected]>--- linux-user/main.c | 5 +++++ target-alpha/helper.h | 2 -- target-alpha/op_helper.c | 28 ++-------------------------- target-alpha/translate.c | 19 +++++++++++++++---- 4 files changed, 22 insertions(+), 32 deletions(-)linux-user/main.c +0
-0
linux-user/main.c void cpu_loop (CPUState *env) · line 2364
Quoted 8 lines
linux-user/main.c +5
-0@@ -2357,6 +2357,11 @@ void cpu_loop (CPUState *env)while (1 ) { trapnr =cpu_alpha_exec (env); +/* All of the traps imply a transition through PALcode, which +implies an REI instruction has been executed. Which means +that the intr_flag should be cleared. */ + env->intr_flag =0 ; +
The indentation here is wrong, you should use spaces instead of tabs.
Quoted 118 lines
linux-user/main.c +0
-0switch (trapnr) {case EXCP_RESET :fprintf (stderr,"Reset requested. Exit\n" );target-alpha/helper.h +0
-2@@ -2,8 +2,6 @@ DEF_HELPER_2(excp, void, int, int) DEF_HELPER_FLAGS_0(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64) -DEF_HELPER_FLAGS_0(rc, TCG_CALL_CONST, i64) -DEF_HELPER_FLAGS_0(rs, TCG_CALL_CONST, i64) DEF_HELPER_2(addqv, i64, i64, i64)DEF_HELPER_2 (addlv, i64, i64, i64)target-alpha/op_helper.c +2
-26@@ -47,32 +47,6 @@ void helper_store_fpcr (uint64_t val)cpu_alpha_store_fpcr (env, val); } -static spinlock_t intr_cpu_lock =SPIN_LOCK_UNLOCKED ; - -uint64_t helper_rs (void ) -{ -uint64_t tmp; - -spin_lock (&intr_cpu_lock); - tmp = env->intr_flag; - env->intr_flag =1 ; -spin_unlock (&intr_cpu_lock); - -return tmp; -} - -uint64_t helper_rc (void ) -{ -uint64_t tmp; - -spin_lock (&intr_cpu_lock); - tmp = env->intr_flag; - env->intr_flag =0 ; -spin_unlock (&intr_cpu_lock); - -return tmp; -} -uint64_t helper_addqv (uint64_t op1,uint64_t op2) {uint64_t tmp = op1;@@ -1211,6 +1185,7 @@ void helper_hw_rei (void) { env->pc = env->ipr[IPR_EXC_ADDR ] & ~3 ; env->ipr[IPR_EXC_ADDR ] = env->ipr[IPR_EXC_ADDR ] &1 ; + env->intr_flag =0 ;/* XXX: re-enable interrupts and memory mapping */ }@@ -1218,6 +1193,7 @@ void helper_hw_ret (uint64_t a) { env->pc = a & ~3 ; env->ipr[IPR_EXC_ADDR ] = a &1 ; + env->intr_flag =0 ;/* XXX: re-enable interrupts and memory mapping */ }target-alpha/translate.c +15
-4@@ -1266,6 +1266,19 @@ static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit,gen_set_label (l2); } +static void gen_rx (int ra,int set) +{ +TCGv_i32 tmp; + +if (ra !=31 ) { +tcg_gen_ld8u_i64 (cpu_ir[ra], cpu_env, offsetof(CPUState , intr_flag)); + } + + tmp =tcg_const_i32 (set); +tcg_gen_st8_i32 (tmp, cpu_env, offsetof(CPUState , intr_flag)); +tcg_temp_free_i32 (tmp); +} +static inline int translate_one (DisasContext *ctx,uint32_t insn) {uint32_t palcode;@@ -2359,16 +2372,14 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0xE000 :/* RC */ -if (ra !=31 ) -gen_helper_rc (cpu_ir[ra]); +gen_rx (ra,0 );break ;case 0xE800 :/* ECB */ break ;case 0xF000 :/* RS */ -if (ra !=31 ) -gen_helper_rs (cpu_ir[ra]); +gen_rx (ra,1 );break ;case 0xF800 :/* WH64 */ Signature · 1 line
1.6.6.1
Signature · 2 lines
Aurelien Jarno GPG: 1024D/F1BCDB73 [email protected] http://www.aurel32.net
PATCH 4/13 target-alpha: Implement cvtql inline.
In reply to Richard HendersonIt's a simple mask and shift sequence.
Also, fix a typo in the actual masks used.
--- target-alpha/helper.h | 4 ---- target-alpha/op_helper.c | 20 -------------------- target-alpha/translate.c | 45 +++++++++++++++++++++++++++++++++++++++------ 3 files changed, 39 insertions(+), 30 deletions(-)
target-alpha/helper.h +0 -4
@@ -89,10 +89,6 @@ DEF_HELPER_FLAGS_1(cvttq, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvttq_c, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvttq_svic, TCG_CALL_CONST, i64, i64) -DEF_HELPER_FLAGS_1(cvtql, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) -DEF_HELPER_1(cvtql_v, i64, i64) -DEF_HELPER_1(cvtql_sv, i64, i64) - DEF_HELPER_FLAGS_1(setroundmode, TCG_CALL_CONST, void, i32) DEF_HELPER_FLAGS_1(setflushzero, TCG_CALL_CONST, void, i32)DEF_HELPER_FLAGS_0 (fp_exc_clear,TCG_CALL_CONST , void)
target-alpha/op_helper.c +0 -20
@@ -1159,26 +1159,6 @@ uint64_t helper_cvtlq (uint64_t a)return (lo &0x3FFFFFFF ) | (hi &0xc0000000 ); } -uint64_t helper_cvtql (uint64_t a) -{ -return ((a &0xC0000000 ) <<32 ) | ((a &0x7FFFFFFF ) <<29 ); -} - -uint64_t helper_cvtql_v (uint64_t a) -{ -if ((int32_t )a != (int64_t )a) -helper_excp (EXCP_ARITH ,EXC_M_IOV ); -return helper_cvtql (a); -} - -uint64_t helper_cvtql_sv (uint64_t a) -{ -/* ??? I'm pretty sure there's nothing that /sv needs to do that /v -doesn't do. The only thing I can think is that /sv is a valid -instruction merely for completeness in the ISA. */ -return helper_cvtql_v (a); -} -/* PALcode support special instructions */ #if !defined (CONFIG_USER_ONLY )void helper_hw_rei (void )
target-alpha/translate.c +39 -6
65 lines not on this page · raw message
Signature · 1 line
1.6.6.1
PATCH 5/13 target-alpha: Implement cvtlq inline.
In reply to Richard HendersonIt's a simple shift and mask sequence.
--- target-alpha/helper.h | 1 - target-alpha/op_helper.c | 7 ------- target-alpha/translate.c | 23 ++++++++++++++++++++++- 3 files changed, 22 insertions(+), 9 deletions(-)
target-alpha/helper.h +0 -1
@@ -83,7 +83,6 @@ DEF_HELPER_FLAGS_1(cvtqf, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvtgf, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvtgq, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvtqg, TCG_CALL_CONST, i64, i64) -DEF_HELPER_FLAGS_1(cvtlq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) DEF_HELPER_FLAGS_1(cvttq, TCG_CALL_CONST, i64, i64)DEF_HELPER_FLAGS_1 (cvttq_c,TCG_CALL_CONST , i64, i64)
target-alpha/op_helper.c +0 -7
@@ -1152,13 +1152,6 @@ uint64_t helper_cvtqg (uint64_t a)return float64_to_g (fr); } -uint64_t helper_cvtlq (uint64_t a) -{ -int32_t lo = a >>29 ; -int32_t hi = a >>32 ; -return (lo &0x3FFFFFFF ) | (hi &0xc0000000 ); -} -/* PALcode support special instructions */ #if !defined (CONFIG_USER_ONLY )void helper_hw_rei (void )
target-alpha/translate.c +22 -1
@@ -597,6 +597,28 @@ static inline void gen_fp_exc_raise(int rc, int fn11)gen_fp_exc_raise_ignore (rc, fn11, fn11 &QUAL_I ?0 : float_flag_inexact); } +static void gen_fcvtlq (int rb,int rc) +{ +if (unlikely (rc ==31 )) { +return ; + } +if (unlikely (rb ==31 )) { +tcg_gen_movi_i64 (cpu_fir[rc],0 ); + }else { +TCGv tmp =tcg_temp_new (); + +/* The arithmetic right shift here, plus the sign-extended mask below +yields a sign-extended result without an explicit ext32s_i64. */ +tcg_gen_sari_i64 (tmp, cpu_fir[rb],32 ); +tcg_gen_shri_i64 (cpu_fir[rc], cpu_fir[rb],29 ); +tcg_gen_andi_i64 (tmp, tmp, (int32_t )0xc0000000 ); +tcg_gen_andi_i64 (cpu_fir[rc], cpu_fir[rc],0x3fffffff ); +tcg_gen_or_i64 (cpu_fir[rc], cpu_fir[rc], tmp); + +tcg_temp_free (tmp); + } +} +static void gen_fcvtql (int rb,int rc) {if (unlikely (rc ==31 )) {
@@ -646,7 +668,6 @@ static inline void glue(gen_f, name)(int rb, int rc) \tcg_temp_free (tmp); \ } \ } -FARITH2 (cvtlq)/* ??? VAX instruction qualifiers ignored. */ FARITH2 (sqrtf)
Signature · 1 line
1.6.6.1
PATCH 6/13 target-alpha: Use setcond for int comparisons.
In reply to Richard Henderson--- target-alpha/translate.c | 43 ++++++++++++++++++++++--------------------- 1 files changed, 22 insertions(+), 21 deletions(-)
target-alpha/translate.c +22 -21
@@ -1290,33 +1290,34 @@ MVIOP2(pkwb)MVIOP2 (unpkbl)MVIOP2 (unpkbw) -static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit, - uint8_t lit) +static void gen_cmp(TCGCond cond, int ra, int rb, int rc, + int islit, uint8_t lit) { - int l1, l2; -TCGv tmp; + TCGv va, vb; - if (unlikely(rc == 31)) + if (unlikely(rc == 31)) {return ; + } - l1 = gen_new_label(); - l2 = gen_new_label(); +if (ra ==31 ) { + va =tcg_const_i64 (0 ); + }else { + va = cpu_ir[ra]; + } +if (islit) { + vb =tcg_const_i64 (lit); + }else { + vb = cpu_ir[rb]; + } - if (ra != 31) { - tmp =tcg_temp_new (); -tcg_gen_mov_i64 (tmp, cpu_ir[ra]); - } else - tmp =tcg_const_i64 (0 ); -if (islit) -tcg_gen_brcondi_i64 (cond, tmp, lit, l1); -else -tcg_gen_brcond_i64 (cond, tmp, cpu_ir[rb], l1); +tcg_gen_setcond_i64 (cond, cpu_ir[rc], va, vb); -tcg_gen_movi_i64 (cpu_ir[rc],0 ); -tcg_gen_br (l2); -gen_set_label (l1); -tcg_gen_movi_i64 (cpu_ir[rc],1 ); -gen_set_label (l2); +if (ra ==31 ) { +tcg_temp_free (va); + } +if (islit) { +tcg_temp_free (vb); + } }static void gen_rx (int ra,int set)
Signature · 1 line
1.6.6.1
Aurelien Jarno
AppliedRe: [Qemu-devel] [PATCH 06/13] target-alpha: Use setcond for int comparisons.
Quoted 4 lines · Richard Henderson
Signed-off-by Richard Henderson <[email protected]>--- target-alpha/translate.c | 43 ++++++++++++++++++++++--------------------- 1 files changed, 22 insertions(+), 21 deletions(-)
Thanks, applied.
Quoted 66 lines
target-alpha/translate.c +22
-21@@ -1290,33 +1290,34 @@ MVIOP2(pkwb)MVIOP2 (unpkbl)MVIOP2 (unpkbw) -static inline void gen_cmp(TCGCond cond, int ra, int rb, int rc, int islit, - uint8_t lit) +static void gen_cmp(TCGCond cond, int ra, int rb, int rc, + int islit, uint8_t lit) { - int l1, l2; -TCGv tmp; + TCGv va, vb; - if (unlikely(rc == 31)) + if (unlikely(rc == 31)) {return ; + } - l1 = gen_new_label(); - l2 = gen_new_label(); +if (ra ==31 ) { + va =tcg_const_i64 (0 ); + }else { + va = cpu_ir[ra]; + } +if (islit) { + vb =tcg_const_i64 (lit); + }else { + vb = cpu_ir[rb]; + } - if (ra != 31) { - tmp =tcg_temp_new (); -tcg_gen_mov_i64 (tmp, cpu_ir[ra]); - } else - tmp =tcg_const_i64 (0 ); -if (islit) -tcg_gen_brcondi_i64 (cond, tmp, lit, l1); -else -tcg_gen_brcond_i64 (cond, tmp, cpu_ir[rb], l1); +tcg_gen_setcond_i64 (cond, cpu_ir[rc], va, vb); -tcg_gen_movi_i64 (cpu_ir[rc],0 ); -tcg_gen_br (l2); -gen_set_label (l1); -tcg_gen_movi_i64 (cpu_ir[rc],1 ); -gen_set_label (l2); +if (ra ==31 ) { +tcg_temp_free (va); + } +if (islit) { +tcg_temp_free (vb); + } }static void gen_rx (int ra,int set)Signature · 1 line
1.6.6.1
Signature · 2 lines
Aurelien Jarno GPG: 1024D/F1BCDB73 [email protected] http://www.aurel32.net
PATCH 7/13 target-alpha: Use non-inverted arguments to gen_{f}cmov.
In reply to Richard HendersonThe inverted conditions as argument to the function looks wrong at a glance inside translate_one. Since we have an easy function to produce the inversion now, use it.
--- target-alpha/translate.c | 37 +++++++++++++++++++------------------ 1 files changed, 19 insertions(+), 18 deletions(-)
target-alpha/translate.c +19 -18
@@ -394,9 +394,10 @@ static void gen_fbcond(DisasContext *ctx, TCGCond cond, int ra, int32_t disp)gen_bcond_pcload (ctx, disp, lab_true); } -static inline void gen_cmov (TCGCond inv_cond,int ra,int rb,int rc, -int islit,uint8_t lit,int mask) +static void gen_cmov (TCGCond cond,int ra,int rb,int rc, +int islit,uint8_t lit,int mask) { +TCGCond inv_cond =tcg_invert_cond (cond);int l1;if (unlikely (rc ==31 ))
@@ -426,7 +427,7 @@ static inline void gen_cmov(TCGCond inv_cond, int ra, int rb, int rc,gen_set_label (l1); } -static void gen_fcmov (TCGCond inv_cond,int ra,int rb,int rc) +static void gen_fcmov (TCGCond cond,int ra,int rb,int rc) {TCGv va = cpu_fir[ra];int l1;
@@ -439,7 +440,7 @@ static void gen_fcmov(TCGCond inv_cond, int ra, int rb, int rc) } l1 =gen_new_label (); -gen_fbcond_internal (inv_cond, va, l1); +gen_fbcond_internal (tcg_invert_cond (cond), va, l1);if (rb !=31 )tcg_gen_mov_i64 (cpu_fir[rc], cpu_fir[rb]);
@@ -1767,11 +1768,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x14 :/* CMOVLBS */ -gen_cmov (TCG_COND_EQ , ra, rb, rc, islit, lit,1 ); +gen_cmov (TCG_COND_NE , ra, rb, rc, islit, lit,1 );break ;case 0x16 :/* CMOVLBC */ -gen_cmov (TCG_COND_NE , ra, rb, rc, islit, lit,1 ); +gen_cmov (TCG_COND_EQ , ra, rb, rc, islit, lit,1 );break ;case 0x20 :/* BIS */
@@ -1791,11 +1792,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x24 :/* CMOVEQ */ -gen_cmov (TCG_COND_NE , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_EQ , ra, rb, rc, islit, lit,0 );break ;case 0x26 :/* CMOVNE */ -gen_cmov (TCG_COND_EQ , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_NE , ra, rb, rc, islit, lit,0 );break ;case 0x28 :/* ORNOT */
@@ -1831,11 +1832,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x44 :/* CMOVLT */ -gen_cmov (TCG_COND_GE , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_LT , ra, rb, rc, islit, lit,0 );break ;case 0x46 :/* CMOVGE */ -gen_cmov (TCG_COND_LT , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_GE , ra, rb, rc, islit, lit,0 );break ;case 0x48 :/* EQV */
@@ -1875,11 +1876,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x64 :/* CMOVLE */ -gen_cmov (TCG_COND_GT , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_LE , ra, rb, rc, islit, lit,0 );break ;case 0x66 :/* CMOVGT */ -gen_cmov (TCG_COND_LE , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_GT , ra, rb, rc, islit, lit,0 );break ;case 0x6C :/* IMPLVER */
@@ -2353,27 +2354,27 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x02A :/* FCMOVEQ */ -gen_fcmov (TCG_COND_NE , ra, rb, rc); +gen_fcmov (TCG_COND_EQ , ra, rb, rc);break ;case 0x02B :/* FCMOVNE */ -gen_fcmov (TCG_COND_EQ , ra, rb, rc); +gen_fcmov (TCG_COND_NE , ra, rb, rc);break ;case 0x02C :/* FCMOVLT */ -gen_fcmov (TCG_COND_GE , ra, rb, rc); +gen_fcmov (TCG_COND_LT , ra, rb, rc);break ;case 0x02D :/* FCMOVGE */ -gen_fcmov (TCG_COND_LT , ra, rb, rc); +gen_fcmov (TCG_COND_GE , ra, rb, rc);break ;case 0x02E :/* FCMOVLE */ -gen_fcmov (TCG_COND_GT , ra, rb, rc); +gen_fcmov (TCG_COND_LE , ra, rb, rc);break ;case 0x02F :/* FCMOVGT */ -gen_fcmov (TCG_COND_LE , ra, rb, rc); +gen_fcmov (TCG_COND_GT , ra, rb, rc);break ;case 0x030 :/* CVTQL */
Signature · 1 line
1.6.6.1
Aurelien Jarno
AppliedRe: [Qemu-devel] [PATCH 07/13] target-alpha: Use non-inverted arguments to gen_{f}cmov.
Quoted 3 lines · Richard Henderson
The inverted conditions as argument to the function looks wrong at a glance inside
translate_one. Since we have an easy function to produce the inversion now, use it.
Thanks, applied.
Quoted 136 lines
Signed-off-by Richard Henderson <[email protected]>--- target-alpha/translate.c | 37 +++++++++++++++++++------------------ 1 files changed, 19 insertions(+), 18 deletions(-)target-alpha/translate.c +19
-18@@ -394,9 +394,10 @@ static void gen_fbcond(DisasContext *ctx, TCGCond cond, int ra, int32_t disp)gen_bcond_pcload (ctx, disp, lab_true); } -static inline void gen_cmov (TCGCond inv_cond,int ra,int rb,int rc, -int islit,uint8_t lit,int mask) +static void gen_cmov (TCGCond cond,int ra,int rb,int rc, +int islit,uint8_t lit,int mask) { +TCGCond inv_cond =tcg_invert_cond (cond);int l1;if (unlikely (rc ==31 ))@@ -426,7 +427,7 @@ static inline void gen_cmov(TCGCond inv_cond, int ra, int rb, int rc,gen_set_label (l1); } -static void gen_fcmov (TCGCond inv_cond,int ra,int rb,int rc) +static void gen_fcmov (TCGCond cond,int ra,int rb,int rc) {TCGv va = cpu_fir[ra];int l1;@@ -439,7 +440,7 @@ static void gen_fcmov(TCGCond inv_cond, int ra, int rb, int rc) } l1 =gen_new_label (); -gen_fbcond_internal (inv_cond, va, l1); +gen_fbcond_internal (tcg_invert_cond (cond), va, l1);if (rb !=31 )tcg_gen_mov_i64 (cpu_fir[rc], cpu_fir[rb]);@@ -1767,11 +1768,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x14 :/* CMOVLBS */ -gen_cmov (TCG_COND_EQ , ra, rb, rc, islit, lit,1 ); +gen_cmov (TCG_COND_NE , ra, rb, rc, islit, lit,1 );break ;case 0x16 :/* CMOVLBC */ -gen_cmov (TCG_COND_NE , ra, rb, rc, islit, lit,1 ); +gen_cmov (TCG_COND_EQ , ra, rb, rc, islit, lit,1 );break ;case 0x20 :/* BIS */ @@ -1791,11 +1792,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x24 :/* CMOVEQ */ -gen_cmov (TCG_COND_NE , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_EQ , ra, rb, rc, islit, lit,0 );break ;case 0x26 :/* CMOVNE */ -gen_cmov (TCG_COND_EQ , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_NE , ra, rb, rc, islit, lit,0 );break ;case 0x28 :/* ORNOT */ @@ -1831,11 +1832,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x44 :/* CMOVLT */ -gen_cmov (TCG_COND_GE , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_LT , ra, rb, rc, islit, lit,0 );break ;case 0x46 :/* CMOVGE */ -gen_cmov (TCG_COND_LT , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_GE , ra, rb, rc, islit, lit,0 );break ;case 0x48 :/* EQV */ @@ -1875,11 +1876,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x64 :/* CMOVLE */ -gen_cmov (TCG_COND_GT , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_LE , ra, rb, rc, islit, lit,0 );break ;case 0x66 :/* CMOVGT */ -gen_cmov (TCG_COND_LE , ra, rb, rc, islit, lit,0 ); +gen_cmov (TCG_COND_GT , ra, rb, rc, islit, lit,0 );break ;case 0x6C :/* IMPLVER */ @@ -2353,27 +2354,27 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x02A :/* FCMOVEQ */ -gen_fcmov (TCG_COND_NE , ra, rb, rc); +gen_fcmov (TCG_COND_EQ , ra, rb, rc);break ;case 0x02B :/* FCMOVNE */ -gen_fcmov (TCG_COND_EQ , ra, rb, rc); +gen_fcmov (TCG_COND_NE , ra, rb, rc);break ;case 0x02C :/* FCMOVLT */ -gen_fcmov (TCG_COND_GE , ra, rb, rc); +gen_fcmov (TCG_COND_LT , ra, rb, rc);break ;case 0x02D :/* FCMOVGE */ -gen_fcmov (TCG_COND_LT , ra, rb, rc); +gen_fcmov (TCG_COND_GE , ra, rb, rc);break ;case 0x02E :/* FCMOVLE */ -gen_fcmov (TCG_COND_GT , ra, rb, rc); +gen_fcmov (TCG_COND_LE , ra, rb, rc);break ;case 0x02F :/* FCMOVGT */ -gen_fcmov (TCG_COND_LE , ra, rb, rc); +gen_fcmov (TCG_COND_GT , ra, rb, rc);break ;case 0x030 :/* CVTQL */ Signature · 1 line
1.6.6.1
Signature · 2 lines
Aurelien Jarno GPG: 1024D/F1BCDB73 [email protected] http://www.aurel32.net
PATCH 8/13 target-alpha: Emit goto_tb opcodes.
In reply to Richard HendersonUse an ExitStatus enumeration instead of magic numbers as the return value from translate_one. Emit goto_tb opcodes when ending a TB via a direct branch.
--- target-alpha/translate.c | 339 ++++++++++++++++++++++++++-------------------- 1 files changed, 193 insertions(+), 146 deletions(-)
target-alpha/translate.c +193 -146
@@ -43,12 +43,13 @@typedef struct DisasContext DisasContext ;struct DisasContext { +struct TranslationBlock *tb; +CPUAlphaState *env;uint64_t pc;int mem_idx;#if !defined (CONFIG_USER_ONLY )int pal_mode;#endif -CPUAlphaState *env;uint32_t amask;/* Current rounding mode for this TB. */
@@ -57,6 +58,25 @@ struct DisasContext {int tb_ftz; }; +/* Return values from translate_one, indicating the state of the TB. +Note that zero indicates that we are not exiting the TB. */ + +typedef enum { +NO_EXIT , + +/* We have emitted one or more goto_tb. No fixup required. */ +EXIT_GOTO_TB , + +/* We are not using a goto_tb (for whatever reason), but have updated +the PC (for whatever reason), so there's no need to do it again on +exiting the TB. */ +EXIT_PC_UPDATED , + +/* We are exiting the TB, but have neither emitted a goto_tb, nor +updated the PC for the next instruction to be executed. */ +EXIT_PC_STALE +}ExitStatus ; +/* global register indexes */ static TCGv_ptr cpu_env;static TCGv cpu_ir[31 ];
@@ -300,77 +320,126 @@ static inline void gen_store_mem(DisasContext *ctx,tcg_temp_free (addr); } -static void gen_bcond_pcload (DisasContext *ctx,int32_t disp,int lab_true) +static int use_goto_tb (DisasContext *ctx,uint64_t dest) { -int lab_over =gen_new_label (); +/* Check for the dest on the same page as the start of the TB. We +also want to suppress goto_tb in the case of single-steping and IO. */ +return (((ctx->tb->pc ^ dest) &TARGET_PAGE_MASK ) ==0 + && !ctx->env->singlestep_enabled + && !(ctx->tb->cflags &CF_LAST_IO )); +} -tcg_gen_movi_i64 (cpu_pc, ctx->pc); -tcg_gen_br (lab_over); -gen_set_label (lab_true); -tcg_gen_movi_i64 (cpu_pc, ctx->pc + (int64_t )(disp <<2 )); -gen_set_label (lab_over); +static ExitStatus gen_bdirect (DisasContext *ctx,int ra,int32_t disp) +{ +uint64_t dest = ctx->pc + (disp <<2 ); + +if (ra !=31 ) { +tcg_gen_movi_i64 (cpu_ir[ra], ctx->pc); + } + +/* Notice branch-to-next; used to initialize RA with the PC. */ +if (disp ==0 ) { +return 0 ; + }else if (use_goto_tb (ctx, dest)) { +tcg_gen_goto_tb (0 ); +tcg_gen_movi_i64 (cpu_pc, dest); +tcg_gen_exit_tb ((long )ctx->tb); +return EXIT_GOTO_TB ; + }else { +tcg_gen_movi_i64 (cpu_pc, dest); +return EXIT_PC_UPDATED ; + } } -static void gen_bcond (DisasContext *ctx,TCGCond cond,int ra, -int32_t disp,int mask) +static ExitStatus gen_bcond_internal (DisasContext *ctx,TCGCond cond, +TCGv cmp,int32_t disp) { +uint64_t dest = ctx->pc + (disp <<2 );int lab_true =gen_new_label (); -if (likely (ra !=31 )) { +if (use_goto_tb (ctx, dest)) { +tcg_gen_brcondi_i64 (cond, cmp,0 , lab_true); + +tcg_gen_goto_tb (0 ); +tcg_gen_movi_i64 (cpu_pc, ctx->pc); +tcg_gen_exit_tb ((long )ctx->tb); + +gen_set_label (lab_true); +tcg_gen_goto_tb (1 ); +tcg_gen_movi_i64 (cpu_pc, dest); +tcg_gen_exit_tb ((long )ctx->tb +1 ); + +return EXIT_GOTO_TB ; + }else { +int lab_over =gen_new_label (); + +/* ??? Consider using either +movi pc, next +addi tmp, pc, disp +movcond pc, cond, 0, tmp, pc +or +setcond tmp, cond, 0 +movi pc, next +neg tmp, tmp +andi tmp, tmp, disp +add pc, pc, tmp +The current diamond subgraph surely isn't efficient. */ + +tcg_gen_brcondi_i64 (cond, cmp,0 , lab_true); +tcg_gen_movi_i64 (cpu_pc, ctx->pc); +tcg_gen_br (lab_over); +gen_set_label (lab_true); +tcg_gen_movi_i64 (cpu_pc, dest); +gen_set_label (lab_over); + +return EXIT_PC_UPDATED ; + } +} + +static ExitStatus gen_bcond (DisasContext *ctx,TCGCond cond,int ra, +int32_t disp,int mask) +{ +TCGv cmp_tmp; + +if (unlikely (ra ==31 )) { + cmp_tmp =tcg_const_i64 (0 ); + }else { + cmp_tmp =tcg_temp_new ();if (mask) { -TCGv tmp =tcg_temp_new (); -tcg_gen_andi_i64 (tmp, cpu_ir[ra],1 ); -tcg_gen_brcondi_i64 (cond, tmp,0 , lab_true); -tcg_temp_free (tmp); +tcg_gen_andi_i64 (cmp_tmp, cpu_ir[ra],1 ); }else { -tcg_gen_brcondi_i64 (cond, cpu_ir[ra],0 , lab_true); +tcg_gen_mov_i64 (cmp_tmp, cpu_ir[ra]); } - }else { -/* Very uncommon case - Do not bother to optimize. */ -TCGv tmp =tcg_const_i64 (0 ); -tcg_gen_brcondi_i64 (cond, tmp,0 , lab_true); -tcg_temp_free (tmp); } -gen_bcond_pcload (ctx, disp, lab_true); + +return gen_bcond_internal (ctx, cond, cmp_tmp, disp); } -/* Generate a forward TCG branch to LAB_TRUE if RA cmp 0.0. -This is complicated by the fact that -0.0 compares the same as +0.0. */ +/* Fold -0.0 for comparison with COND. */ -static void gen_fbcond_internal (TCGCond cond,TCGv src,int lab_true) +static void gen_fold_mzero (TCGCond cond,TCGv dest,TCGv src) { -int lab_false =-1 ;uint64_t mzero =1ull <<63 ; -TCGv tmp;switch (cond) {case TCG_COND_LE :case TCG_COND_GT :/* For <= or >, the -0.0 value directly compares the way we want. */ -tcg_gen_brcondi_i64 (cond, src,0 , lab_true); +tcg_gen_mov_i64 (dest, src);break ;case TCG_COND_EQ :case TCG_COND_NE :/* For == or !=, we can simply mask off the sign bit and compare. */ -/* ??? Assume that the temporary is reclaimed at the branch. */ - tmp =tcg_temp_new (); -tcg_gen_andi_i64 (tmp, src, mzero -1 ); -tcg_gen_brcondi_i64 (cond, tmp,0 , lab_true); +tcg_gen_andi_i64 (dest, src, mzero -1 );break ;case TCG_COND_GE : -/* For >=, emit two branches to the destination. */ -tcg_gen_brcondi_i64 (cond, src,0 , lab_true); -tcg_gen_brcondi_i64 (TCG_COND_EQ , src, mzero, lab_true); -break ; -case TCG_COND_LT : -/* For <, first filter out -0.0 to what will be the fallthru. */ - lab_false =gen_new_label (); -tcg_gen_brcondi_i64 (TCG_COND_EQ , src, mzero, lab_false); -tcg_gen_brcondi_i64 (cond, src,0 , lab_true); -gen_set_label (lab_false); +/* For >= or <, map -0.0 to +0.0 via comparison and mask. */ +tcg_gen_setcondi_i64 (TCG_COND_NE , dest, src, mzero); +tcg_gen_neg_i64 (dest, dest); +tcg_gen_and_i64 (dest, dest, src);break ;default :
@@ -378,24 +447,24 @@ static void gen_fbcond_internal(TCGCond cond, TCGv src, int lab_true) } } -static void gen_fbcond (DisasContext *ctx,TCGCond cond,int ra,int32_t disp) +static ExitStatus gen_fbcond (DisasContext *ctx,TCGCond cond,int ra, +int32_t disp) { -int lab_true; +TCGv cmp_tmp;if (unlikely (ra ==31 )) {/* Very uncommon case, but easier to optimize it to an integer comparison than continuing with the floating point comparison. */ -gen_bcond (ctx, cond, ra, disp,0 ); -return ; +return gen_bcond (ctx, cond, ra, disp,0 ); } - lab_true =gen_new_label (); -gen_fbcond_internal (cond, cpu_fir[ra], lab_true); -gen_bcond_pcload (ctx, disp, lab_true); + cmp_tmp =tcg_temp_new (); +gen_fold_mzero (cond, cmp_tmp, cpu_fir[ra]); +return gen_bcond_internal (ctx, cond, cmp_tmp, disp); }static void gen_cmov (TCGCond cond,int ra,int rb,int rc, -int islit,uint8_t lit,int mask) +int islit,uint8_t lit,int mask) {TCGCond inv_cond =tcg_invert_cond (cond);int l1;
@@ -429,18 +498,23 @@ static void gen_cmov(TCGCond cond, int ra, int rb, int rc,static void gen_fcmov (TCGCond cond,int ra,int rb,int rc) { -TCGv va = cpu_fir[ra]; +TCGv cmp_tmp;int l1; -if (unlikely (rc ==31 )) +if (unlikely (rc ==31 )) {return ; + } + + cmp_tmp =tcg_temp_new ();if (unlikely (ra ==31 )) { -/* ??? Assume that the temporary is reclaimed at the branch. */ - va =tcg_const_i64 (0 ); +tcg_gen_movi_i64 (cmp_tmp,0 ); + }else { +gen_fold_mzero (cond, cmp_tmp, cpu_fir[ra]); } l1 =gen_new_label (); -gen_fbcond_internal (tcg_invert_cond (cond), va, l1); +tcg_gen_brcondi_i64 (tcg_invert_cond (cond), cmp_tmp,0 , l1); +tcg_temp_free (cmp_tmp);if (rb !=31 )tcg_gen_mov_i64 (cpu_fir[rc], cpu_fir[rb]);
@@ -1334,14 +1408,14 @@ static void gen_rx(int ra, int set)tcg_temp_free_i32 (tmp); } -static inline int translate_one (DisasContext *ctx,uint32_t insn) +static ExitStatus translate_one (DisasContext *ctx,uint32_t insn) {uint32_t palcode;int32_t disp21, disp16, disp12;uint16_t fn11, fn16;uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit, real_islit;uint8_t lit; -int ret; +ExitStatus ret;/* Decode all instruction fields */ opc = insn >>26 ;
@@ -1364,10 +1438,10 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn) fpfn = fn11 &0x3F ; fn7 = (insn >>5 ) &0x0000007F ; fn2 = (insn >>5 ) &0x00000003 ; - ret =0 ;LOG_DISAS ("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n" , opc, ra, rb, rc, disp16); + ret =NO_EXIT ;switch (opc) {case 0x00 :/* CALL_PAL */
@@ -1385,7 +1459,8 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)if (palcode >=0x80 && palcode <0xC0 ) {/* Unprivileged PAL call */ gen_excp (ctx,EXCP_CALL_PAL + ((palcode &0x3F ) <<6 ),0 ); - ret =3 ; +/* PC updated by gen_excp. */ + ret =EXIT_PC_UPDATED ;break ; }#ifndef CONFIG_USER_ONLY
@@ -1394,7 +1469,8 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)if (ctx->mem_idx &1 ) goto invalid_opc;gen_excp (ctx,EXCP_CALL_PALP + ((palcode &0x3F ) <<6 ),0 ); - ret = 3; +/* PC updated by gen_excp. */ + ret = EXIT_PC_UPDATED; }#endif /* Invalid PAL call */
@@ -2397,13 +2473,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)switch ((uint16_t )disp16) {case 0x0000 :/* TRAPB */ -/* No-op. Just exit from the current tb */ - ret =2 ; +/* No-op. */ break ;case 0x0400 :/* EXCB */ -/* No-op. Just exit from the current tb */ - ret =2 ; +/* No-op. */ break ;case 0x4000 :/* MB */
@@ -2467,21 +2541,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)if (ra !=31 )tcg_gen_movi_i64 (cpu_ir[ra], ctx->pc);/* Those four jumps only differ by the branch prediction hint */ -switch (fn2) { -case 0x0 : -/* JMP */ -break ; -case 0x1 : -/* JSR */ -break ; -case 0x2 : -/* RET */ -break ; -case 0x3 : -/* JSR_COROUTINE */ -break ; - } - ret =1 ; + ret =EXIT_PC_UPDATED ;break ;case 0x1B :/* HW_LD (PALcode) */
@@ -2772,7 +2832,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn) tcg_temp_free(tmp2); }tcg_temp_free (tmp1); - ret =2 ; + ret =EXIT_PC_STALE ; }break ;#endif
@@ -2797,7 +2857,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)gen_helper_hw_ret (tmp); tcg_temp_free(tmp); } - ret =2 ; + ret =EXIT_PC_UPDATED ;break ;#endif case 0x1F :
@@ -2958,85 +3018,66 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x30 :/* BR */ -if (ra !=31 ) -tcg_gen_movi_i64 (cpu_ir[ra], ctx->pc); -tcg_gen_movi_i64 (cpu_pc, ctx->pc + (int64_t )(disp21 <<2 )); - ret =1 ; + ret =gen_bdirect (ctx, ra, disp21);break ;case 0x31 :/* FBEQ */ -gen_fbcond (ctx,TCG_COND_EQ , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_EQ , ra, disp21);break ;case 0x32 :/* FBLT */ -gen_fbcond (ctx,TCG_COND_LT , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_LT , ra, disp21);break ;case 0x33 :/* FBLE */ -gen_fbcond (ctx,TCG_COND_LE , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_LE , ra, disp21);break ;case 0x34 :/* BSR */ -if (ra !=31 ) -tcg_gen_movi_i64 (cpu_ir[ra], ctx->pc); -tcg_gen_movi_i64 (cpu_pc, ctx->pc + (int64_t )(disp21 <<2 )); - ret =1 ; + ret =gen_bdirect (ctx, ra, disp21);break ;case 0x35 :/* FBNE */ -gen_fbcond (ctx,TCG_COND_NE , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_NE , ra, disp21);break ;case 0x36 :/* FBGE */ -gen_fbcond (ctx,TCG_COND_GE , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_GE , ra, disp21);break ;case 0x37 :/* FBGT */ -gen_fbcond (ctx,TCG_COND_GT , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_GT , ra, disp21);break ;case 0x38 :/* BLBC */ -gen_bcond (ctx,TCG_COND_EQ , ra, disp21,1 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_EQ , ra, disp21,1 );break ;case 0x39 :/* BEQ */ -gen_bcond (ctx,TCG_COND_EQ , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_EQ , ra, disp21,0 );break ;case 0x3A :/* BLT */ -gen_bcond (ctx,TCG_COND_LT , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_LT , ra, disp21,0 );break ;case 0x3B :/* BLE */ -gen_bcond (ctx,TCG_COND_LE , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_LE , ra, disp21,0 );break ;case 0x3C :/* BLBS */ -gen_bcond (ctx,TCG_COND_NE , ra, disp21,1 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_NE , ra, disp21,1 );break ;case 0x3D :/* BNE */ -gen_bcond (ctx,TCG_COND_NE , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_NE , ra, disp21,0 );break ;case 0x3E :/* BGE */ -gen_bcond (ctx,TCG_COND_GE , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_GE , ra, disp21,0 );break ;case 0x3F :/* BGT */ -gen_bcond (ctx,TCG_COND_GT , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_GT , ra, disp21,0 );break ; invalid_opc:gen_invalid (ctx); - ret =3 ; +/* PC updated by gen_excp. */ + ret =EXIT_PC_UPDATED ;break ; }
@@ -3053,15 +3094,17 @@ static inline void gen_intermediate_code_internal(CPUState *env,uint16_t *gen_opc_end;CPUBreakpoint *bp;int j, lj =-1 ; -int ret; +ExitStatus ret;int num_insns;int max_insns; pc_start = tb->pc; gen_opc_end = gen_opc_buf +OPC_MAX_SIZE ; + + ctx.tb = tb; + ctx.env = env; ctx.pc = pc_start; ctx.amask = env->amask; - ctx.env = env;#if defined (CONFIG_USER_ONLY ) ctx.mem_idx =0 ;#else
@@ -3085,7 +3128,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, max_insns =CF_COUNT_MASK ;gen_icount_start (); -for (ret =0 ; ret ==0 ;) { + do { if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { QTAILQ_FOREACH(bp, &env->breakpoints, entry) { if (bp->pc == ctx.pc) {
@@ -3116,36 +3159,39 @@ static inline void gen_intermediate_code_internal(CPUState *env, ctx.pc +=4 ; ret =translate_one (ctxp, insn); -if (ret !=0 ) -break ; -/* if we reach a page boundary or are single stepping, stop -* generation -*/ -if (env->singlestep_enabled) { -gen_excp (&ctx,EXCP_DEBUG ,0 ); -break ; - } -if ((ctx.pc & (TARGET_PAGE_SIZE -1 )) ==0 ) -break ; - -if (gen_opc_ptr >= gen_opc_end) -break ; - -if (num_insns >= max_insns) -break ; - -if (singlestep) { -break ; +if (ret ==NO_EXIT ) { +/* If we reach a page boundary, are single stepping, +or exhaust instruction count, stop generation. */ +if (env->singlestep_enabled) { +gen_excp (&ctx,EXCP_DEBUG ,0 ); + ret =EXIT_PC_UPDATED ; + }else if ((ctx.pc & (TARGET_PAGE_SIZE -1 )) ==0 + || gen_opc_ptr >= gen_opc_end + || num_insns >= max_insns + || singlestep) { + ret =EXIT_PC_STALE ; + } } + }while (ret ==NO_EXIT ); + +if (tb->cflags &CF_LAST_IO ) { +gen_io_end (); } -if (ret !=1 && ret !=3 ) { + +switch (ret) { +case EXIT_GOTO_TB : +break ; +case EXIT_PC_STALE :tcg_gen_movi_i64 (cpu_pc, ctx.pc); +/* FALLTHRU */ +case EXIT_PC_UPDATED : +tcg_gen_exit_tb (0 ); +break ; +default : +abort (); } -if (tb->cflags &CF_LAST_IO ) -gen_io_end (); -/* Generate the return instruction */ -tcg_gen_exit_tb (0 ); +gen_icount_end (tb, num_insns); *gen_opc_ptr = INDEX_op_end;if (search_pc) {
@@ -3157,6 +3203,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, tb->size = ctx.pc - pc_start; tb->icount = num_insns; } +#ifdef DEBUG_DISAS if (qemu_loglevel_mask (CPU_LOG_TB_IN_ASM )) {qemu_log ("IN: %s\n" ,lookup_symbol (pc_start));
Signature · 1 line
1.6.6.1
PATCH 9/13 target-alpha: Update commentary for opcode 0x1A.
In reply to Richard Henderson--- target-alpha/translate.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-)
target-alpha/translate.c +7 -4
@@ -2534,13 +2534,16 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)break ;#endif case 0x1A : -if (rb !=31 ) +/* JMP, JSR, RET, JSR_COROUTINE. These only differ by the branch +prediction stack action, which of course we don't implement. */ +if (rb !=31 ) {tcg_gen_andi_i64 (cpu_pc, cpu_ir[rb], ~3 ); -else + }else {tcg_gen_movi_i64 (cpu_pc,0 ); -if (ra !=31 ) + } +if (ra !=31 ) {tcg_gen_movi_i64 (cpu_ir[ra], ctx->pc); -/* Those four jumps only differ by the branch prediction hint */ + } ret =EXIT_PC_UPDATED ;break ;case 0x1B :
Signature · 1 line
1.6.6.1
PATCH 10/13 target-alpha: Enable NPTL.
In reply to Richard Henderson--- configure | 1 + linux-user/syscall.c | 2 +- target-alpha/cpu.h | 28 +++++++++++++++++----------- 3 files changed, 19 insertions(+), 12 deletions(-)
configure +1 -0
@@ -2430,6 +2430,7 @@ case "$target_arch2" in ;; alpha) target_phys_bits=64 + target_nptl="yes" ;; arm|armeb) TARGET_ARCH=arm
linux-user/syscall.c +1 -1
@@ -5768,7 +5768,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret =get_errno (fsync (arg1));break ;case TARGET_NR_clone: -#if defined(TARGET_SH4 ) +#if defined(TARGET_SH4 ) || defined(TARGET_ALPHA ) ret =get_errno (do_fork (cpu_env, arg1, arg2, arg3, arg5, arg4));#elif defined(TARGET_CRIS ) ret =get_errno (do_fork (cpu_env, arg2, arg1, arg3, arg4, arg5));
target-alpha/cpu.h +17 -11
@@ -411,15 +411,6 @@ static inline int cpu_mmu_index (CPUState *env)return (env->ps >>3 ) &3 ; } -#if defined(CONFIG_USER_ONLY ) -static inline void cpu_clone_regs (CPUState *env,target_ulong newsp) -{ -if (newsp) - env->ir[30 ] = newsp; -/* FIXME: Zero syscall return value. */ -} -#endif -#include "cpu-all.h" #include "exec-all.h"
@@ -477,7 +468,7 @@ enum {IR_S4 =13 ,IR_S5 =14 ,IR_S6 =15 , -#define IR_FP IR_S6 +IR_FP =IR_S6 ,IR_A0 =16 ,IR_A1 =17 , IR_A2 = 18,
@@ -490,7 +481,7 @@ enum {IR_T11 =25 ,IR_RA =26 ,IR_T12 =27 , -#define IR_PV IR_T12 +IR_PV =IR_T12 ,IR_AT =28 ,IR_GP =29 , IR_SP = 30,
@@ -531,4 +522,19 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, *flags = env->ps; } +#if defined(CONFIG_USER_ONLY ) +static inline void cpu_clone_regs (CPUState *env,target_ulong newsp) +{ +if (newsp) + env->ir[IR_SP ] = newsp; + env->ir[IR_V0 ] =0 ; + env->ir[IR_A3 ] =0 ; +} + +static inline void cpu_set_tls (CPUState *env,target_ulong newtls) +{ + env->unique = newtls; +} +#endif +#endif /* !defined (__CPU_ALPHA_H__) */
Signature · 1 line
1.6.6.1
Re: [Qemu-devel] [PATCH 10/13] target-alpha: Enable NPTL.
Quoted 71 lines · Richard Henderson
Signed-off-by Richard Henderson <[email protected]>--- configure | 1 + linux-user/syscall.c | 2 +- target-alpha/cpu.h | 28 +++++++++++++++++----------- 3 files changed, 19 insertions(+), 12 deletions(-)configure +1
-0@@ -2430,6 +2430,7 @@ case "$target_arch2" in ;; alpha) target_phys_bits=64 + target_nptl="yes" ;; arm|armeb) TARGET_ARCH=armlinux-user/syscall.c +1
-1@@ -5768,7 +5768,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret =get_errno (fsync (arg1));break ;case TARGET_NR_clone: -#if defined(TARGET_SH4 ) +#if defined(TARGET_SH4 ) || defined(TARGET_ALPHA ) ret =get_errno (do_fork (cpu_env, arg1, arg2, arg3, arg5, arg4));#elif defined(TARGET_CRIS ) ret =get_errno (do_fork (cpu_env, arg2, arg1, arg3, arg4, arg5));target-alpha/cpu.h +2
-11@@ -411,15 +411,6 @@ static inline int cpu_mmu_index (CPUState *env)return (env->ps >>3 ) &3 ; } -#if defined(CONFIG_USER_ONLY ) -static inline void cpu_clone_regs (CPUState *env,target_ulong newsp) -{ -if (newsp) - env->ir[30 ] = newsp; -/* FIXME: Zero syscall return value. */ -} -#endif -#include "cpu-all.h" #include "exec-all.h" @@ -477,7 +468,7 @@ enum {IR_S4 =13 ,IR_S5 =14 ,IR_S6 =15 , -#define IR_FP IR_S6 +IR_FP =IR_S6 ,IR_A0 =16 ,IR_A1 =17 , IR_A2 = 18,@@ -490,7 +481,7 @@ enum {IR_T11 =25 ,IR_RA =26 ,IR_T12 =27 , -#define IR_PV IR_T12 +IR_PV =IR_T12 ,IR_AT =28 ,IR_GP =29 , IR_SP = 30,
target-alpha/cpu.h static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, · line 529
Quoted 8 lines
target-alpha/cpu.h +5
-0@@ -531,4 +522,19 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, *flags = env->ps; } +#if defined(CONFIG_USER_ONLY ) +static inline void cpu_clone_regs (CPUState *env,target_ulong newsp) +{ +if (newsp) + env->ir[IR_SP ] = newsp;
You need curly braces here.
Quoted 17 lines
target-alpha/cpu.h +10
-0+ env->ir[IR_V0 ] =0 ; + env->ir[IR_A3 ] =0 ; +} + +static inline void cpu_set_tls (CPUState *env,target_ulong newtls) +{ + env->unique = newtls; +} +#endif +#endif /* !defined (__CPU_ALPHA_H__) */ Signature · 1 line
1.6.6.1
Signature · 2 lines
Aurelien Jarno GPG: 1024D/F1BCDB73 [email protected] http://www.aurel32.net
PATCH 11/13 target-alpha: Indicate NORETURN status when raising exception.
In reply to Richard HendersonWhen (indirectly) calling raise_exception, don't emit cleanup code at the end of the TB, as it is unused.
--- target-alpha/translate.c | 27 ++++++++++++++------------- 1 files changed, 14 insertions(+), 13 deletions(-)
target-alpha/translate.c +14 -13
@@ -74,7 +74,11 @@ typedef enum {/* We are exiting the TB, but have neither emitted a goto_tb, nor updated the PC for the next instruction to be executed. */ - EXIT_PC_STALE +EXIT_PC_STALE , + +/* We are ending the TB with a noreturn function call, e.g. longjmp. +No following code will be executed. */ +EXIT_NORETURN , } ExitStatus;/* global register indexes */
@@ -134,7 +138,7 @@ static void alpha_translate_init(void) done_init =1 ; } -static inline void gen_excp (DisasContext *ctx,int exception,int error_code) +static ExitStatus gen_excp (DisasContext *ctx,int exception,int error_code) {TCGv_i32 tmp1, tmp2;
@@ -144,11 +148,13 @@ static inline void gen_excp(DisasContext *ctx, int exception, int error_code)gen_helper_excp (tmp1, tmp2);tcg_temp_free_i32 (tmp2);tcg_temp_free_i32 (tmp1); + +return EXIT_NORETURN ; } -static inline void gen_invalid (DisasContext *ctx) +static inline ExitStatus gen_invalid (DisasContext *ctx) { -gen_excp (ctx,EXCP_OPCDEC ,0 ); +return gen_excp (ctx,EXCP_OPCDEC ,0 ); }static inline void gen_qemu_ldf (TCGv t0,TCGv t1,int flags)
@@ -1458,9 +1464,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)#endif if (palcode >=0x80 && palcode <0xC0 ) {/* Unprivileged PAL call */ -gen_excp (ctx,EXCP_CALL_PAL + ((palcode &0x3F ) <<6 ),0 ); -/* PC updated by gen_excp. */ - ret =EXIT_PC_UPDATED ; + ret =gen_excp (ctx,EXCP_CALL_PAL + ((palcode &0x3F ) <<6 ),0 );break ; }#ifndef CONFIG_USER_ONLY
@@ -1468,9 +1472,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)/* Privileged PAL code */ if (ctx->mem_idx &1 ) goto invalid_opc; -gen_excp (ctx,EXCP_CALL_PALP + ((palcode &0x3F ) <<6 ),0 ); -/* PC updated by gen_excp. */ - ret = EXIT_PC_UPDATED; + ret = gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0); }#endif /* Invalid PAL call */
@@ -3078,9 +3080,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) ret =gen_bcond (ctx,TCG_COND_GT , ra, disp21,0 );break ; invalid_opc: -gen_invalid (ctx); -/* PC updated by gen_excp. */ - ret =EXIT_PC_UPDATED ; + ret =gen_invalid (ctx);break ; }
@@ -3184,6 +3184,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,switch (ret) {case EXIT_GOTO_TB : +case EXIT_NORETURN :break ;case EXIT_PC_STALE :tcg_gen_movi_i64 (cpu_pc, ctx.pc);
Signature · 1 line
1.6.6.1
PATCH 12/13 target-alpha: Fix load-locked/store-conditional.
In reply to Richard HendersonUse an exception plus start_exclusive to implement the compare-and-swap. This follows the example set by the MIPS and PPC ports.
--- linux-user/main.c | 55 +++++++++++++ target-alpha/cpu.h | 6 +- target-alpha/helper.c | 7 +- target-alpha/op_helper.c | 2 + target-alpha/translate.c | 202 ++++++++++++++++++++++++++++----------------- 5 files changed, 193 insertions(+), 79 deletions(-)
linux-user/main.c +55 -0
@@ -2348,6 +2348,51 @@ void cpu_loop(CPUM68KState *env)#endif /* TARGET_M68K */ #ifdef TARGET_ALPHA +static void do_store_exclusive (CPUAlphaState *env,int reg,int quad) +{ +target_ulong addr, val, tmp; +target_siginfo_t info; +int ret =0 ; + + addr = env->lock_addr; + tmp = env->lock_st_addr; + env->lock_addr =-1 ; + env->lock_st_addr =0 ; + +start_exclusive (); +mmap_lock (); + +if (addr == tmp) { +if (quad ?get_user_s64 (val, addr) :get_user_s32 (val, addr)) { + goto do_sigsegv; + } + +if (val == env->lock_value) { + tmp = env->ir[reg]; +if (quad ?put_user_u64 (tmp, addr) :put_user_u32 (tmp, addr)) { + goto do_sigsegv; + } + ret =1 ; + } + } + env->ir[reg] = ret; + env->pc +=4 ; + +mmap_unlock (); +end_exclusive (); +return ; + + do_sigsegv: +mmap_unlock (); +end_exclusive (); + + info.si_signo =TARGET_SIGSEGV ; + info.si_errno =0 ; + info.si_code =TARGET_SEGV_MAPERR ; + info._sifields._sigfault._addr = addr; +queue_signal (env,TARGET_SIGSEGV , &info); +} +void cpu_loop (CPUState *env) {int trapnr;
@@ -2372,6 +2417,7 @@ void cpu_loop (CPUState *env)exit (1 );break ;case EXCP_ARITH : + env->lock_addr =-1 ; info.si_signo =TARGET_SIGFPE ; info.si_errno =0 ; info.si_code =TARGET_FPE_FLTINV ;
@@ -2383,6 +2429,7 @@ void cpu_loop (CPUState *env)exit (1 );break ;case EXCP_DFAULT : + env->lock_addr =-1 ; info.si_signo =TARGET_SIGSEGV ; info.si_errno =0 ; info.si_code =0 ;/* ??? SEGV_MAPERR vs SEGV_ACCERR. */
@@ -2406,6 +2453,7 @@ void cpu_loop (CPUState *env)exit (1 );break ;case EXCP_UNALIGN : + env->lock_addr =-1 ; info.si_signo =TARGET_SIGBUS ; info.si_errno =0 ; info.si_code =TARGET_BUS_ADRALN ;
@@ -2414,6 +2462,7 @@ void cpu_loop (CPUState *env)break ;case EXCP_OPCDEC : do_sigill: + env->lock_addr =-1 ; info.si_signo =TARGET_SIGILL ; info.si_errno =0 ; info.si_code =TARGET_ILL_ILLOPC ;
@@ -2424,6 +2473,7 @@ void cpu_loop (CPUState *env)/* No-op. Linux simply re-enables the FPU. */ break ; case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1): + env->lock_addr =-1 ;switch ((trapnr >>6 ) |0x80 ) {case 0x80 :/* BPT */
@@ -2513,11 +2563,16 @@ void cpu_loop (CPUState *env)case EXCP_DEBUG : info.si_signo =gdb_handlesig (env,TARGET_SIGTRAP );if (info.si_signo) { + env->lock_addr =-1 ; info.si_errno =0 ; info.si_code =TARGET_TRAP_BRKPT ;queue_signal (env, info.si_signo, &info); }break ; +case EXCP_STL_C : +case EXCP_STQ_C : +do_store_exclusive (env, env->error_code, trapnr -EXCP_STL_C ); +break ;default :printf ("Unhandled trap: 0x%x\n" , trapnr);cpu_dump_state (env, stderr, fprintf,0 );
target-alpha/cpu.h +5 -1
@@ -355,11 +355,13 @@ struct CPUAlphaState {uint64_t ir[31 ];float64 fir[31 ];uint64_t pc; -uint64_t lock;uint32_t pcc[2 ];uint64_t ipr[IPR_LAST ];uint64_t ps;uint64_t unique; +uint64_t lock_addr; +uint64_t lock_st_addr; +uint64_t lock_value;float_status fp_status;/* The following fields make up the FPCR, but in FP_STATUS format. */ uint8_t fpcr_exc_status;
@@ -440,6 +442,8 @@ enum {/* Pseudo exception for console */ EXCP_CONSOLE_DISPATCH =0x4001 ,EXCP_CONSOLE_FIXUP =0x4002 , +EXCP_STL_C =0x4003 , + EXCP_STQ_C = 0x4004, };/* Arithmetic exception */
target-alpha/helper.c +5 -2
@@ -556,12 +556,15 @@ void cpu_dump_state (CPUState *env, FILE *f,if ((i %3 ) ==2 )cpu_fprintf (f,"\n" ); } -cpu_fprintf (f,"\n" ); + +cpu_fprintf (f,"lock_a " TARGET_FMT_lx" lock_v " TARGET_FMT_lx"\n" , + env->lock_addr, env->lock_value); +for (i =0 ; i <31 ; i++) {cpu_fprintf (f,"FIR%02d " TARGET_FMT_lx" " , i, *((uint64_t *)(&env->fir[i])));if ((i %3 ) ==2 )cpu_fprintf (f,"\n" ); } -cpu_fprintf (f,"\nlock " TARGET_FMT_lx"\n" , env->lock); +cpu_fprintf (f,"\n" ); }
target-alpha/op_helper.c +2 -0
@@ -1159,6 +1159,7 @@ void helper_hw_rei (void) env->pc = env->ipr[IPR_EXC_ADDR ] & ~3 ; env->ipr[IPR_EXC_ADDR ] = env->ipr[IPR_EXC_ADDR ] &1 ; env->intr_flag =0 ; + env->lock_addr =-1 ;/* XXX: re-enable interrupts and memory mapping */ }
@@ -1167,6 +1168,7 @@ void helper_hw_ret (uint64_t a) env->pc = a & ~3 ; env->ipr[IPR_EXC_ADDR ] = a &1 ; env->intr_flag =0 ; + env->lock_addr =-1 ;/* XXX: re-enable interrupts and memory mapping */ }
target-alpha/translate.c +126 -76
312 lines not on this page · raw message
Signature · 1 line
1.6.6.1
PATCH 13/13 target-alpha: Implement RPCC.
In reply to Richard HendersonA minimal implementation that more or less corresponds to the user-level version used by target-i386. More hoops will want to be jumped through when alpha gets system-level emulation.
--- qemu-timer.h | 13 +++++++++++++ target-alpha/cpu.h | 1 - target-alpha/op_helper.c | 5 +++-- 3 files changed, 16 insertions(+), 3 deletions(-)
qemu-timer.h +13 -0
@@ -209,6 +209,19 @@ static inline int64_t cpu_get_real_ticks(void) return (int64_t)(count * cyc_per_count); } +#elif defined(__alpha__) + +static inline int64_t cpu_get_real_ticks (void ) +{ +uint64_t cc; +uint32_t cur, ofs; + + asmvolatile ("rpcc %0" :"=r" (cc)); + cur = cc; + ofs = cc >>32 ; +return cur - ofs; +} +#else /* The host CPU doesn't have an easily accessible cycle counter. Just return a monotonically increasing value. This will be
target-alpha/cpu.h +0 -1
@@ -355,7 +355,6 @@ struct CPUAlphaState {uint64_t ir[31 ];float64 fir[31 ];uint64_t pc; -uint32_t pcc[2 ];uint64_t ipr[IPR_LAST ];uint64_t ps;uint64_t unique;
target-alpha/op_helper.c +3 -2
@@ -21,6 +21,7 @@#include "host-utils.h" #include "softfloat.h" #include "helper.h" +#include "qemu-timer.h" /*****************************************************************************/ /* Exceptions processing helpers */
@@ -33,8 +34,8 @@ void QEMU_NORETURN helper_excp (int excp, int error)uint64_t helper_load_pcc (void ) { -/* XXX: TODO */ -return 0 ; +/* ??? This isn't a timer for which we have any rate info. */ +return (uint32_t )cpu_get_real_ticks (); }uint64_t helper_load_fpcr (void )
Signature · 1 line
1.6.6.1
Re: [Qemu-devel] [PATCH 13/13] target-alpha: Implement RPCC.
Quoted 3 lines · Richard Henderson
A minimal implementation that more or less corresponds to the user-level version used by target-i386. More hoops will want to be jumped through when alpha gets system-level emulation.
This patch looks ok, but it mixed host and target changes. Can you please split it?
Quoted 72 lines
Signed-off-by Richard Henderson <[email protected]>--- qemu-timer.h | 13 +++++++++++++ target-alpha/cpu.h | 1 - target-alpha/op_helper.c | 5 +++-- 3 files changed, 16 insertions(+), 3 deletions(-)qemu-timer.h +13
-0@@ -209,6 +209,19 @@ static inline int64_t cpu_get_real_ticks(void) return (int64_t)(count * cyc_per_count); } +#elif defined(__alpha__) + +static inline int64_t cpu_get_real_ticks (void ) +{ +uint64_t cc; +uint32_t cur, ofs; + + asmvolatile ("rpcc %0" :"=r" (cc)); + cur = cc; + ofs = cc >>32 ; +return cur - ofs; +} +#else /* The host CPU doesn't have an easily accessible cycle counter. Just return a monotonically increasing value. This will be target-alpha/cpu.h +0
-1@@ -355,7 +355,6 @@ struct CPUAlphaState {uint64_t ir[31 ];float64 fir[31 ];uint64_t pc; -uint32_t pcc[2 ];uint64_t ipr[IPR_LAST ];uint64_t ps;uint64_t unique;target-alpha/op_helper.c +3
-2@@ -21,6 +21,7 @@#include "host-utils.h" #include "softfloat.h" #include "helper.h" +#include "qemu-timer.h" /*****************************************************************************/ /* Exceptions processing helpers */ @@ -33,8 +34,8 @@ void QEMU_NORETURN helper_excp (int excp, int error)uint64_t helper_load_pcc (void ) { -/* XXX: TODO */ -return 0 ; +/* ??? This isn't a timer for which we have any rate info. */ +return (uint32_t )cpu_get_real_ticks (); }uint64_t helper_load_fpcr (void )Signature · 1 line
1.6.6.1
Signature · 2 lines
Aurelien Jarno GPG: 1024D/F1BCDB73 [email protected] http://www.aurel32.net
cover target-alpha improvments, version 5
In reply to Richard HendersonChanges from v4->v5:
* Re-base vs master, and accepted patches.
* Address the comments from version 4.
r~
Richard Henderson (10):
target-alpha: Implement cpys{,n,e} inline.
target-alpha: Implement rs/rc properly.
target-alpha: Implement cvtlq inline.
target-alpha: Emit goto_tb opcodes.
target-alpha: Update commentary for opcode 0x1A.
target-alpha: Enable NPTL.
target-alpha: Indicate NORETURN status when raising exception.
target-alpha: Fix load-locked/store-conditional.
target-alpha: Implement RPCC.
Implement cpu_get_real_ticks for Alpha.
configure | 1 + linux-user/main.c | 62 ++++- linux-user/syscall.c | 2 +- qemu-timer.h | 13 + target-alpha/cpu.h | 36 ++- target-alpha/helper.c | 7 +- target-alpha/helper.h | 7 - target-alpha/op_helper.c | 60 +---- target-alpha/translate.c | 684 ++++++++++++++++++++++++++++++---------------- 9 files changed, 555 insertions(+), 317 deletions(-)
PATCH 1/10 target-alpha: Implement cpys{, n, e} inline.
--- target-alpha/helper.h | 4 -- target-alpha/op_helper.c | 18 ---------- target-alpha/translate.c | 79 +++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 75 insertions(+), 26 deletions(-)
target-alpha/helper.h +0 -4
@@ -77,10 +77,6 @@ DEF_HELPER_FLAGS_2(cmpgeq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) DEF_HELPER_FLAGS_2(cmpgle, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) DEF_HELPER_FLAGS_2(cmpglt, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) -DEF_HELPER_FLAGS_2(cpys, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) -DEF_HELPER_FLAGS_2(cpysn, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) -DEF_HELPER_FLAGS_2(cpyse, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64, i64) - DEF_HELPER_FLAGS_1(cvtts, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvtst, TCG_CALL_CONST, i64, i64)DEF_HELPER_FLAGS_1 (cvtqs,TCG_CALL_CONST , i64, i64)
target-alpha/op_helper.c +0 -18
@@ -921,24 +921,6 @@ uint64_t helper_sqrtt (uint64_t a)return float64_to_t (fr); } - -/* Sign copy */ -uint64_t helper_cpys (uint64_t a,uint64_t b) -{ -return (a &0x8000000000000000ULL ) | (b & ~0x8000000000000000ULL ); -} - -uint64_t helper_cpysn (uint64_t a,uint64_t b) -{ -return ((~a) &0x8000000000000000ULL ) | (b & ~0x8000000000000000ULL ); -} - -uint64_t helper_cpyse (uint64_t a,uint64_t b) -{ -return (a &0xFFF0000000000000ULL ) | (b & ~0xFFF0000000000000ULL ); -} - -/* Comparisons */ uint64_t helper_cmptun (uint64_t a,uint64_t b) {
target-alpha/translate.c +75 -4
91 lines not on this page · raw message
Signature · 1 line
1.6.2.5
PATCH 2/10 target-alpha: Implement rs/rc properly.
In reply to Richard HendersonThis is a per-cpu flag; there's no need for a spinlock of any kind.
We were also failing to manipulate the flag with $31 as a target reg and failing to clear the flag on execution of a return-from-interrupt instruction.
--- linux-user/main.c | 7 ++++++- target-alpha/helper.h | 2 -- target-alpha/op_helper.c | 28 ++-------------------------- target-alpha/translate.c | 19 +++++++++++++++---- 4 files changed, 23 insertions(+), 33 deletions(-)
linux-user/main.c +6 -1
@@ -2357,6 +2357,11 @@ void cpu_loop (CPUState *env)while (1 ) { trapnr =cpu_alpha_exec (env); +/* All of the traps imply a transition through PALcode, which +implies an REI instruction has been executed. Which means +that the intr_flag should be cleared. */ + env->intr_flag =0 ; +switch (trapnr) {case EXCP_RESET :fprintf (stderr,"Reset requested. Exit\n" );
@@ -2443,7 +2448,7 @@ void cpu_loop (CPUState *env) env->ir[IR_A0 ], env->ir[IR_A1 ], env->ir[IR_A2 ], env->ir[IR_A3 ], env->ir[IR_A4], env->ir[IR_A5]); -if (trapnr != TARGET_NR_sigreturn +if (trapnr != TARGET_NR_sigreturn && trapnr != TARGET_NR_rt_sigreturn) { env->ir[IR_V0 ] = (sysret <0 ? -sysret : sysret); env->ir[IR_A3 ] = (sysret <0 );
target-alpha/helper.h +0 -2
@@ -2,8 +2,6 @@ DEF_HELPER_2(excp, void, int, int) DEF_HELPER_FLAGS_0(load_pcc, TCG_CALL_CONST | TCG_CALL_PURE, i64) -DEF_HELPER_FLAGS_0(rc, TCG_CALL_CONST, i64) -DEF_HELPER_FLAGS_0(rs, TCG_CALL_CONST, i64) DEF_HELPER_2(addqv, i64, i64, i64)DEF_HELPER_2 (addlv, i64, i64, i64)
target-alpha/op_helper.c +2 -26
@@ -47,32 +47,6 @@ void helper_store_fpcr (uint64_t val)cpu_alpha_store_fpcr (env, val); } -static spinlock_t intr_cpu_lock =SPIN_LOCK_UNLOCKED ; - -uint64_t helper_rs (void ) -{ -uint64_t tmp; - -spin_lock (&intr_cpu_lock); - tmp = env->intr_flag; - env->intr_flag =1 ; -spin_unlock (&intr_cpu_lock); - -return tmp; -} - -uint64_t helper_rc (void ) -{ -uint64_t tmp; - -spin_lock (&intr_cpu_lock); - tmp = env->intr_flag; - env->intr_flag =0 ; -spin_unlock (&intr_cpu_lock); - -return tmp; -} -uint64_t helper_addqv (uint64_t op1,uint64_t op2) {uint64_t tmp = op1;
@@ -1191,6 +1165,7 @@ void helper_hw_rei (void) { env->pc = env->ipr[IPR_EXC_ADDR ] & ~3 ; env->ipr[IPR_EXC_ADDR ] = env->ipr[IPR_EXC_ADDR ] &1 ; + env->intr_flag =0 ;/* XXX: re-enable interrupts and memory mapping */ }
@@ -1198,6 +1173,7 @@ void helper_hw_ret (uint64_t a) { env->pc = a & ~3 ; env->ipr[IPR_EXC_ADDR ] = a &1 ; + env->intr_flag =0 ;/* XXX: re-enable interrupts and memory mapping */ }
target-alpha/translate.c +15 -4
@@ -1301,6 +1301,19 @@ static void gen_cmp(TCGCond cond, int ra, int rb, int rc, } } +static void gen_rx (int ra,int set) +{ +TCGv_i32 tmp; + +if (ra !=31 ) { +tcg_gen_ld8u_i64 (cpu_ir[ra], cpu_env, offsetof(CPUState , intr_flag)); + } + + tmp =tcg_const_i32 (set); +tcg_gen_st8_i32 (tmp, cpu_env, offsetof(CPUState , intr_flag)); +tcg_temp_free_i32 (tmp); +} +static inline int translate_one (DisasContext *ctx,uint32_t insn) {uint32_t palcode;
@@ -2395,16 +2408,14 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0xE000 :/* RC */ -if (ra !=31 ) -gen_helper_rc (cpu_ir[ra]); +gen_rx (ra,0 );break ;case 0xE800 :/* ECB */ break ;case 0xF000 :/* RS */ -if (ra !=31 ) -gen_helper_rs (cpu_ir[ra]); +gen_rx (ra,1 );break ;case 0xF800 :/* WH64 */
Signature · 1 line
1.6.2.5
PATCH 3/10 target-alpha: Implement cvtlq inline.
In reply to Richard HendersonIt's a simple shift and mask sequence.
--- target-alpha/helper.h | 1 - target-alpha/op_helper.c | 7 ------- target-alpha/translate.c | 23 ++++++++++++++++++++++- 3 files changed, 22 insertions(+), 9 deletions(-)
target-alpha/helper.h +0 -1
@@ -83,7 +83,6 @@ DEF_HELPER_FLAGS_1(cvtqf, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvtgf, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvtgq, TCG_CALL_CONST, i64, i64) DEF_HELPER_FLAGS_1(cvtqg, TCG_CALL_CONST, i64, i64) -DEF_HELPER_FLAGS_1(cvtlq, TCG_CALL_CONST | TCG_CALL_PURE, i64, i64) DEF_HELPER_FLAGS_1(cvttq, TCG_CALL_CONST, i64, i64)DEF_HELPER_FLAGS_1 (cvttq_c,TCG_CALL_CONST , i64, i64)
target-alpha/op_helper.c +0 -7
@@ -1152,13 +1152,6 @@ uint64_t helper_cvtqg (uint64_t a)return float64_to_g (fr); } -uint64_t helper_cvtlq (uint64_t a) -{ -int32_t lo = a >>29 ; -int32_t hi = a >>32 ; -return (lo &0x3FFFFFFF ) | (hi &0xc0000000 ); -} -/* PALcode support special instructions */ #if !defined (CONFIG_USER_ONLY )void helper_hw_rei (void )
target-alpha/translate.c +22 -1
@@ -598,6 +598,28 @@ static inline void gen_fp_exc_raise(int rc, int fn11)gen_fp_exc_raise_ignore (rc, fn11, fn11 &QUAL_I ?0 : float_flag_inexact); } +static void gen_fcvtlq (int rb,int rc) +{ +if (unlikely (rc ==31 )) { +return ; + } +if (unlikely (rb ==31 )) { +tcg_gen_movi_i64 (cpu_fir[rc],0 ); + }else { +TCGv tmp =tcg_temp_new (); + +/* The arithmetic right shift here, plus the sign-extended mask below +yields a sign-extended result without an explicit ext32s_i64. */ +tcg_gen_sari_i64 (tmp, cpu_fir[rb],32 ); +tcg_gen_shri_i64 (cpu_fir[rc], cpu_fir[rb],29 ); +tcg_gen_andi_i64 (tmp, tmp, (int32_t )0xc0000000 ); +tcg_gen_andi_i64 (cpu_fir[rc], cpu_fir[rc],0x3fffffff ); +tcg_gen_or_i64 (cpu_fir[rc], cpu_fir[rc], tmp); + +tcg_temp_free (tmp); + } +} +static void gen_fcvtql (int rb,int rc) {if (unlikely (rc ==31 )) {
@@ -647,7 +669,6 @@ static inline void glue(gen_f, name)(int rb, int rc) \tcg_temp_free (tmp); \ } \ } -FARITH2 (cvtlq)/* ??? VAX instruction qualifiers ignored. */ FARITH2 (sqrtf)
Signature · 1 line
1.6.2.5
PATCH 4/10 target-alpha: Emit goto_tb opcodes.
In reply to Richard HendersonUse an ExitStatus enumeration instead of magic numbers as the return value from translate_one. Emit goto_tb opcodes when ending a TB via a direct branch.
--- target-alpha/translate.c | 339 ++++++++++++++++++++++++++-------------------- 1 files changed, 193 insertions(+), 146 deletions(-)
target-alpha/translate.c +193 -146
@@ -43,12 +43,13 @@typedef struct DisasContext DisasContext ;struct DisasContext { +struct TranslationBlock *tb; +CPUAlphaState *env;uint64_t pc;int mem_idx;#if !defined (CONFIG_USER_ONLY )int pal_mode;#endif -CPUAlphaState *env;uint32_t amask;/* Current rounding mode for this TB. */
@@ -57,6 +58,25 @@ struct DisasContext {int tb_ftz; }; +/* Return values from translate_one, indicating the state of the TB. +Note that zero indicates that we are not exiting the TB. */ + +typedef enum { +NO_EXIT , + +/* We have emitted one or more goto_tb. No fixup required. */ +EXIT_GOTO_TB , + +/* We are not using a goto_tb (for whatever reason), but have updated +the PC (for whatever reason), so there's no need to do it again on +exiting the TB. */ +EXIT_PC_UPDATED , + +/* We are exiting the TB, but have neither emitted a goto_tb, nor +updated the PC for the next instruction to be executed. */ +EXIT_PC_STALE +}ExitStatus ; +/* global register indexes */ static TCGv_ptr cpu_env;static TCGv cpu_ir[31 ];
@@ -300,77 +320,126 @@ static inline void gen_store_mem(DisasContext *ctx,tcg_temp_free (addr); } -static void gen_bcond_pcload (DisasContext *ctx,int32_t disp,int lab_true) +static int use_goto_tb (DisasContext *ctx,uint64_t dest) { -int lab_over =gen_new_label (); +/* Check for the dest on the same page as the start of the TB. We +also want to suppress goto_tb in the case of single-steping and IO. */ +return (((ctx->tb->pc ^ dest) &TARGET_PAGE_MASK ) ==0 + && !ctx->env->singlestep_enabled + && !(ctx->tb->cflags &CF_LAST_IO )); +} -tcg_gen_movi_i64 (cpu_pc, ctx->pc); -tcg_gen_br (lab_over); -gen_set_label (lab_true); -tcg_gen_movi_i64 (cpu_pc, ctx->pc + (int64_t )(disp <<2 )); -gen_set_label (lab_over); +static ExitStatus gen_bdirect (DisasContext *ctx,int ra,int32_t disp) +{ +uint64_t dest = ctx->pc + (disp <<2 ); + +if (ra !=31 ) { +tcg_gen_movi_i64 (cpu_ir[ra], ctx->pc); + } + +/* Notice branch-to-next; used to initialize RA with the PC. */ +if (disp ==0 ) { +return 0 ; + }else if (use_goto_tb (ctx, dest)) { +tcg_gen_goto_tb (0 ); +tcg_gen_movi_i64 (cpu_pc, dest); +tcg_gen_exit_tb ((long )ctx->tb); +return EXIT_GOTO_TB ; + }else { +tcg_gen_movi_i64 (cpu_pc, dest); +return EXIT_PC_UPDATED ; + } } -static void gen_bcond (DisasContext *ctx,TCGCond cond,int ra, -int32_t disp,int mask) +static ExitStatus gen_bcond_internal (DisasContext *ctx,TCGCond cond, +TCGv cmp,int32_t disp) { +uint64_t dest = ctx->pc + (disp <<2 );int lab_true =gen_new_label (); -if (likely (ra !=31 )) { +if (use_goto_tb (ctx, dest)) { +tcg_gen_brcondi_i64 (cond, cmp,0 , lab_true); + +tcg_gen_goto_tb (0 ); +tcg_gen_movi_i64 (cpu_pc, ctx->pc); +tcg_gen_exit_tb ((long )ctx->tb); + +gen_set_label (lab_true); +tcg_gen_goto_tb (1 ); +tcg_gen_movi_i64 (cpu_pc, dest); +tcg_gen_exit_tb ((long )ctx->tb +1 ); + +return EXIT_GOTO_TB ; + }else { +int lab_over =gen_new_label (); + +/* ??? Consider using either +movi pc, next +addi tmp, pc, disp +movcond pc, cond, 0, tmp, pc +or +setcond tmp, cond, 0 +movi pc, next +neg tmp, tmp +andi tmp, tmp, disp +add pc, pc, tmp +The current diamond subgraph surely isn't efficient. */ + +tcg_gen_brcondi_i64 (cond, cmp,0 , lab_true); +tcg_gen_movi_i64 (cpu_pc, ctx->pc); +tcg_gen_br (lab_over); +gen_set_label (lab_true); +tcg_gen_movi_i64 (cpu_pc, dest); +gen_set_label (lab_over); + +return EXIT_PC_UPDATED ; + } +} + +static ExitStatus gen_bcond (DisasContext *ctx,TCGCond cond,int ra, +int32_t disp,int mask) +{ +TCGv cmp_tmp; + +if (unlikely (ra ==31 )) { + cmp_tmp =tcg_const_i64 (0 ); + }else { + cmp_tmp =tcg_temp_new ();if (mask) { -TCGv tmp =tcg_temp_new (); -tcg_gen_andi_i64 (tmp, cpu_ir[ra],1 ); -tcg_gen_brcondi_i64 (cond, tmp,0 , lab_true); -tcg_temp_free (tmp); +tcg_gen_andi_i64 (cmp_tmp, cpu_ir[ra],1 ); }else { -tcg_gen_brcondi_i64 (cond, cpu_ir[ra],0 , lab_true); +tcg_gen_mov_i64 (cmp_tmp, cpu_ir[ra]); } - }else { -/* Very uncommon case - Do not bother to optimize. */ -TCGv tmp =tcg_const_i64 (0 ); -tcg_gen_brcondi_i64 (cond, tmp,0 , lab_true); -tcg_temp_free (tmp); } -gen_bcond_pcload (ctx, disp, lab_true); + +return gen_bcond_internal (ctx, cond, cmp_tmp, disp); } -/* Generate a forward TCG branch to LAB_TRUE if RA cmp 0.0. -This is complicated by the fact that -0.0 compares the same as +0.0. */ +/* Fold -0.0 for comparison with COND. */ -static void gen_fbcond_internal (TCGCond cond,TCGv src,int lab_true) +static void gen_fold_mzero (TCGCond cond,TCGv dest,TCGv src) { -int lab_false =-1 ;uint64_t mzero =1ull <<63 ; -TCGv tmp;switch (cond) {case TCG_COND_LE :case TCG_COND_GT :/* For <= or >, the -0.0 value directly compares the way we want. */ -tcg_gen_brcondi_i64 (cond, src,0 , lab_true); +tcg_gen_mov_i64 (dest, src);break ;case TCG_COND_EQ :case TCG_COND_NE :/* For == or !=, we can simply mask off the sign bit and compare. */ -/* ??? Assume that the temporary is reclaimed at the branch. */ - tmp =tcg_temp_new (); -tcg_gen_andi_i64 (tmp, src, mzero -1 ); -tcg_gen_brcondi_i64 (cond, tmp,0 , lab_true); +tcg_gen_andi_i64 (dest, src, mzero -1 );break ;case TCG_COND_GE : -/* For >=, emit two branches to the destination. */ -tcg_gen_brcondi_i64 (cond, src,0 , lab_true); -tcg_gen_brcondi_i64 (TCG_COND_EQ , src, mzero, lab_true); -break ; -case TCG_COND_LT : -/* For <, first filter out -0.0 to what will be the fallthru. */ - lab_false =gen_new_label (); -tcg_gen_brcondi_i64 (TCG_COND_EQ , src, mzero, lab_false); -tcg_gen_brcondi_i64 (cond, src,0 , lab_true); -gen_set_label (lab_false); +/* For >= or <, map -0.0 to +0.0 via comparison and mask. */ +tcg_gen_setcondi_i64 (TCG_COND_NE , dest, src, mzero); +tcg_gen_neg_i64 (dest, dest); +tcg_gen_and_i64 (dest, dest, src);break ;default :
@@ -378,24 +447,24 @@ static void gen_fbcond_internal(TCGCond cond, TCGv src, int lab_true) } } -static void gen_fbcond (DisasContext *ctx,TCGCond cond,int ra,int32_t disp) +static ExitStatus gen_fbcond (DisasContext *ctx,TCGCond cond,int ra, +int32_t disp) { -int lab_true; +TCGv cmp_tmp;if (unlikely (ra ==31 )) {/* Very uncommon case, but easier to optimize it to an integer comparison than continuing with the floating point comparison. */ -gen_bcond (ctx, cond, ra, disp,0 ); -return ; +return gen_bcond (ctx, cond, ra, disp,0 ); } - lab_true =gen_new_label (); -gen_fbcond_internal (cond, cpu_fir[ra], lab_true); -gen_bcond_pcload (ctx, disp, lab_true); + cmp_tmp =tcg_temp_new (); +gen_fold_mzero (cond, cmp_tmp, cpu_fir[ra]); +return gen_bcond_internal (ctx, cond, cmp_tmp, disp); }static void gen_cmov (TCGCond cond,int ra,int rb,int rc, -int islit,uint8_t lit,int mask) +int islit,uint8_t lit,int mask) {TCGCond inv_cond =tcg_invert_cond (cond);int l1;
@@ -429,18 +498,23 @@ static void gen_cmov(TCGCond cond, int ra, int rb, int rc,static void gen_fcmov (TCGCond cond,int ra,int rb,int rc) { -TCGv va = cpu_fir[ra]; +TCGv cmp_tmp;int l1; -if (unlikely (rc ==31 )) +if (unlikely (rc ==31 )) {return ; + } + + cmp_tmp =tcg_temp_new ();if (unlikely (ra ==31 )) { -/* ??? Assume that the temporary is reclaimed at the branch. */ - va =tcg_const_i64 (0 ); +tcg_gen_movi_i64 (cmp_tmp,0 ); + }else { +gen_fold_mzero (cond, cmp_tmp, cpu_fir[ra]); } l1 =gen_new_label (); -gen_fbcond_internal (tcg_invert_cond (cond), va, l1); +tcg_gen_brcondi_i64 (tcg_invert_cond (cond), cmp_tmp,0 , l1); +tcg_temp_free (cmp_tmp);if (rb !=31 )tcg_gen_mov_i64 (cpu_fir[rc], cpu_fir[rb]);
@@ -1335,14 +1409,14 @@ static void gen_rx(int ra, int set)tcg_temp_free_i32 (tmp); } -static inline int translate_one (DisasContext *ctx,uint32_t insn) +static ExitStatus translate_one (DisasContext *ctx,uint32_t insn) {uint32_t palcode;int32_t disp21, disp16, disp12;uint16_t fn11, fn16;uint8_t opc, ra, rb, rc, sbz, fpfn, fn7, fn2, islit, real_islit;uint8_t lit; -int ret; +ExitStatus ret;/* Decode all instruction fields */ opc = insn >>26 ;
@@ -1365,10 +1439,10 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn) fpfn = fn11 &0x3F ; fn7 = (insn >>5 ) &0x0000007F ; fn2 = (insn >>5 ) &0x00000003 ; - ret =0 ;LOG_DISAS ("opc %02x ra %2d rb %2d rc %2d disp16 %6d\n" , opc, ra, rb, rc, disp16); + ret =NO_EXIT ;switch (opc) {case 0x00 :/* CALL_PAL */
@@ -1386,7 +1460,8 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)if (palcode >=0x80 && palcode <0xC0 ) {/* Unprivileged PAL call */ gen_excp (ctx,EXCP_CALL_PAL + ((palcode &0x3F ) <<6 ),0 ); - ret =3 ; +/* PC updated by gen_excp. */ + ret =EXIT_PC_UPDATED ;break ; }#ifndef CONFIG_USER_ONLY
@@ -1395,7 +1470,8 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)if (ctx->mem_idx &1 ) goto invalid_opc;gen_excp (ctx,EXCP_CALL_PALP + ((palcode &0x3F ) <<6 ),0 ); - ret = 3; +/* PC updated by gen_excp. */ + ret = EXIT_PC_UPDATED; }#endif /* Invalid PAL call */
@@ -2398,13 +2474,11 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)switch ((uint16_t )disp16) {case 0x0000 :/* TRAPB */ -/* No-op. Just exit from the current tb */ - ret =2 ; +/* No-op. */ break ;case 0x0400 :/* EXCB */ -/* No-op. Just exit from the current tb */ - ret =2 ; +/* No-op. */ break ;case 0x4000 :/* MB */
@@ -2468,21 +2542,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)if (ra !=31 )tcg_gen_movi_i64 (cpu_ir[ra], ctx->pc);/* Those four jumps only differ by the branch prediction hint */ -switch (fn2) { -case 0x0 : -/* JMP */ -break ; -case 0x1 : -/* JSR */ -break ; -case 0x2 : -/* RET */ -break ; -case 0x3 : -/* JSR_COROUTINE */ -break ; - } - ret =1 ; + ret =EXIT_PC_UPDATED ;break ;case 0x1B :/* HW_LD (PALcode) */
@@ -2773,7 +2833,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn) tcg_temp_free(tmp2); }tcg_temp_free (tmp1); - ret =2 ; + ret =EXIT_PC_STALE ; }break ;#endif
@@ -2798,7 +2858,7 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)gen_helper_hw_ret (tmp); tcg_temp_free(tmp); } - ret =2 ; + ret =EXIT_PC_UPDATED ;break ;#endif case 0x1F :
@@ -2959,85 +3019,66 @@ static inline int translate_one(DisasContext *ctx, uint32_t insn)break ;case 0x30 :/* BR */ -if (ra !=31 ) -tcg_gen_movi_i64 (cpu_ir[ra], ctx->pc); -tcg_gen_movi_i64 (cpu_pc, ctx->pc + (int64_t )(disp21 <<2 )); - ret =1 ; + ret =gen_bdirect (ctx, ra, disp21);break ;case 0x31 :/* FBEQ */ -gen_fbcond (ctx,TCG_COND_EQ , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_EQ , ra, disp21);break ;case 0x32 :/* FBLT */ -gen_fbcond (ctx,TCG_COND_LT , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_LT , ra, disp21);break ;case 0x33 :/* FBLE */ -gen_fbcond (ctx,TCG_COND_LE , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_LE , ra, disp21);break ;case 0x34 :/* BSR */ -if (ra !=31 ) -tcg_gen_movi_i64 (cpu_ir[ra], ctx->pc); -tcg_gen_movi_i64 (cpu_pc, ctx->pc + (int64_t )(disp21 <<2 )); - ret =1 ; + ret =gen_bdirect (ctx, ra, disp21);break ;case 0x35 :/* FBNE */ -gen_fbcond (ctx,TCG_COND_NE , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_NE , ra, disp21);break ;case 0x36 :/* FBGE */ -gen_fbcond (ctx,TCG_COND_GE , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_GE , ra, disp21);break ;case 0x37 :/* FBGT */ -gen_fbcond (ctx,TCG_COND_GT , ra, disp21); - ret =1 ; + ret =gen_fbcond (ctx,TCG_COND_GT , ra, disp21);break ;case 0x38 :/* BLBC */ -gen_bcond (ctx,TCG_COND_EQ , ra, disp21,1 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_EQ , ra, disp21,1 );break ;case 0x39 :/* BEQ */ -gen_bcond (ctx,TCG_COND_EQ , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_EQ , ra, disp21,0 );break ;case 0x3A :/* BLT */ -gen_bcond (ctx,TCG_COND_LT , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_LT , ra, disp21,0 );break ;case 0x3B :/* BLE */ -gen_bcond (ctx,TCG_COND_LE , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_LE , ra, disp21,0 );break ;case 0x3C :/* BLBS */ -gen_bcond (ctx,TCG_COND_NE , ra, disp21,1 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_NE , ra, disp21,1 );break ;case 0x3D :/* BNE */ -gen_bcond (ctx,TCG_COND_NE , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_NE , ra, disp21,0 );break ;case 0x3E :/* BGE */ -gen_bcond (ctx,TCG_COND_GE , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_GE , ra, disp21,0 );break ;case 0x3F :/* BGT */ -gen_bcond (ctx,TCG_COND_GT , ra, disp21,0 ); - ret =1 ; + ret =gen_bcond (ctx,TCG_COND_GT , ra, disp21,0 );break ; invalid_opc:gen_invalid (ctx); - ret =3 ; +/* PC updated by gen_excp. */ + ret =EXIT_PC_UPDATED ;break ; }
@@ -3054,15 +3095,17 @@ static inline void gen_intermediate_code_internal(CPUState *env,uint16_t *gen_opc_end;CPUBreakpoint *bp;int j, lj =-1 ; -int ret; +ExitStatus ret;int num_insns;int max_insns; pc_start = tb->pc; gen_opc_end = gen_opc_buf +OPC_MAX_SIZE ; + + ctx.tb = tb; + ctx.env = env; ctx.pc = pc_start; ctx.amask = env->amask; - ctx.env = env;#if defined (CONFIG_USER_ONLY ) ctx.mem_idx =0 ;#else
@@ -3086,7 +3129,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, max_insns =CF_COUNT_MASK ;gen_icount_start (); -for (ret =0 ; ret ==0 ;) { + do { if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { QTAILQ_FOREACH(bp, &env->breakpoints, entry) { if (bp->pc == ctx.pc) {
@@ -3117,36 +3160,39 @@ static inline void gen_intermediate_code_internal(CPUState *env, ctx.pc +=4 ; ret =translate_one (ctxp, insn); -if (ret !=0 ) -break ; -/* if we reach a page boundary or are single stepping, stop -* generation -*/ -if (env->singlestep_enabled) { -gen_excp (&ctx,EXCP_DEBUG ,0 ); -break ; - } -if ((ctx.pc & (TARGET_PAGE_SIZE -1 )) ==0 ) -break ; - -if (gen_opc_ptr >= gen_opc_end) -break ; - -if (num_insns >= max_insns) -break ; - -if (singlestep) { -break ; +if (ret ==NO_EXIT ) { +/* If we reach a page boundary, are single stepping, +or exhaust instruction count, stop generation. */ +if (env->singlestep_enabled) { +gen_excp (&ctx,EXCP_DEBUG ,0 ); + ret =EXIT_PC_UPDATED ; + }else if ((ctx.pc & (TARGET_PAGE_SIZE -1 )) ==0 + || gen_opc_ptr >= gen_opc_end + || num_insns >= max_insns + || singlestep) { + ret =EXIT_PC_STALE ; + } } + }while (ret ==NO_EXIT ); + +if (tb->cflags &CF_LAST_IO ) { +gen_io_end (); } -if (ret !=1 && ret !=3 ) { + +switch (ret) { +case EXIT_GOTO_TB : +break ; +case EXIT_PC_STALE :tcg_gen_movi_i64 (cpu_pc, ctx.pc); +/* FALLTHRU */ +case EXIT_PC_UPDATED : +tcg_gen_exit_tb (0 ); +break ; +default : +abort (); } -if (tb->cflags &CF_LAST_IO ) -gen_io_end (); -/* Generate the return instruction */ -tcg_gen_exit_tb (0 ); +gen_icount_end (tb, num_insns); *gen_opc_ptr = INDEX_op_end;if (search_pc) {
@@ -3158,6 +3204,7 @@ static inline void gen_intermediate_code_internal(CPUState *env, tb->size = ctx.pc - pc_start; tb->icount = num_insns; } +#ifdef DEBUG_DISAS if (qemu_loglevel_mask (CPU_LOG_TB_IN_ASM )) {qemu_log ("IN: %s\n" ,lookup_symbol (pc_start));
Signature · 1 line
1.6.2.5
PATCH 5/10 target-alpha: Update commentary for opcode 0x1A.
In reply to Richard Henderson--- target-alpha/translate.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-)
target-alpha/translate.c +7 -4
@@ -2535,13 +2535,16 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)break ;#endif case 0x1A : -if (rb !=31 ) +/* JMP, JSR, RET, JSR_COROUTINE. These only differ by the branch +prediction stack action, which of course we don't implement. */ +if (rb !=31 ) {tcg_gen_andi_i64 (cpu_pc, cpu_ir[rb], ~3 ); -else + }else {tcg_gen_movi_i64 (cpu_pc,0 ); -if (ra !=31 ) + } +if (ra !=31 ) {tcg_gen_movi_i64 (cpu_ir[ra], ctx->pc); -/* Those four jumps only differ by the branch prediction hint */ + } ret =EXIT_PC_UPDATED ;break ;case 0x1B :
Signature · 1 line
1.6.2.5
PATCH 6/10 target-alpha: Enable NPTL.
In reply to Richard Henderson--- configure | 1 + linux-user/syscall.c | 2 +- target-alpha/cpu.h | 29 ++++++++++++++++++----------- 3 files changed, 20 insertions(+), 12 deletions(-)
configure +1 -0
@@ -2433,6 +2433,7 @@ case "$target_arch2" in ;; alpha) target_phys_bits=64 + target_nptl="yes" ;; arm|armeb) TARGET_ARCH=arm
linux-user/syscall.c +1 -1
@@ -5768,7 +5768,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, ret =get_errno (fsync (arg1));break ;case TARGET_NR_clone: -#if defined(TARGET_SH4 ) +#if defined(TARGET_SH4 ) || defined(TARGET_ALPHA ) ret =get_errno (do_fork (cpu_env, arg1, arg2, arg3, arg5, arg4));#elif defined(TARGET_CRIS ) ret =get_errno (do_fork (cpu_env, arg2, arg1, arg3, arg4, arg5));
target-alpha/cpu.h +18 -11
@@ -411,15 +411,6 @@ static inline int cpu_mmu_index (CPUState *env)return (env->ps >>3 ) &3 ; } -#if defined(CONFIG_USER_ONLY ) -static inline void cpu_clone_regs (CPUState *env,target_ulong newsp) -{ -if (newsp) - env->ir[30 ] = newsp; -/* FIXME: Zero syscall return value. */ -} -#endif -#include "cpu-all.h" #include "exec-all.h"
@@ -477,7 +468,7 @@ enum {IR_S4 =13 ,IR_S5 =14 ,IR_S6 =15 , -#define IR_FP IR_S6 +IR_FP =IR_S6 ,IR_A0 =16 ,IR_A1 =17 , IR_A2 = 18,
@@ -490,7 +481,7 @@ enum {IR_T11 =25 ,IR_RA =26 ,IR_T12 =27 , -#define IR_PV IR_T12 +IR_PV =IR_T12 ,IR_AT =28 ,IR_GP =29 , IR_SP = 30,
@@ -531,4 +522,20 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, *flags = env->ps; } +#if defined(CONFIG_USER_ONLY ) +static inline void cpu_clone_regs (CPUState *env,target_ulong newsp) +{ +if (newsp) { + env->ir[IR_SP ] = newsp; + } + env->ir[IR_V0 ] =0 ; + env->ir[IR_A3 ] =0 ; +} + +static inline void cpu_set_tls (CPUState *env,target_ulong newtls) +{ + env->unique = newtls; +} +#endif +#endif /* !defined (__CPU_ALPHA_H__) */
Signature · 1 line
1.6.2.5
PATCH 7/10 target-alpha: Indicate NORETURN status when raising exception.
In reply to Richard HendersonWhen (indirectly) calling raise_exception, don't emit cleanup code at the end of the TB, as it is unused.
--- target-alpha/translate.c | 27 ++++++++++++++------------- 1 files changed, 14 insertions(+), 13 deletions(-)
target-alpha/translate.c +14 -13
@@ -74,7 +74,11 @@ typedef enum {/* We are exiting the TB, but have neither emitted a goto_tb, nor updated the PC for the next instruction to be executed. */ - EXIT_PC_STALE +EXIT_PC_STALE , + +/* We are ending the TB with a noreturn function call, e.g. longjmp. +No following code will be executed. */ +EXIT_NORETURN , } ExitStatus;/* global register indexes */
@@ -134,7 +138,7 @@ static void alpha_translate_init(void) done_init =1 ; } -static inline void gen_excp (DisasContext *ctx,int exception,int error_code) +static ExitStatus gen_excp (DisasContext *ctx,int exception,int error_code) {TCGv_i32 tmp1, tmp2;
@@ -144,11 +148,13 @@ static inline void gen_excp(DisasContext *ctx, int exception, int error_code)gen_helper_excp (tmp1, tmp2);tcg_temp_free_i32 (tmp2);tcg_temp_free_i32 (tmp1); + +return EXIT_NORETURN ; } -static inline void gen_invalid (DisasContext *ctx) +static inline ExitStatus gen_invalid (DisasContext *ctx) { -gen_excp (ctx,EXCP_OPCDEC ,0 ); +return gen_excp (ctx,EXCP_OPCDEC ,0 ); }static inline void gen_qemu_ldf (TCGv t0,TCGv t1,int flags)
@@ -1459,9 +1465,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)#endif if (palcode >=0x80 && palcode <0xC0 ) {/* Unprivileged PAL call */ -gen_excp (ctx,EXCP_CALL_PAL + ((palcode &0x3F ) <<6 ),0 ); -/* PC updated by gen_excp. */ - ret =EXIT_PC_UPDATED ; + ret =gen_excp (ctx,EXCP_CALL_PAL + ((palcode &0x3F ) <<6 ),0 );break ; }#ifndef CONFIG_USER_ONLY
@@ -1469,9 +1473,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)/* Privileged PAL code */ if (ctx->mem_idx &1 ) goto invalid_opc; -gen_excp (ctx,EXCP_CALL_PALP + ((palcode &0x3F ) <<6 ),0 ); -/* PC updated by gen_excp. */ - ret = EXIT_PC_UPDATED; + ret = gen_excp(ctx, EXCP_CALL_PALP + ((palcode & 0x3F) << 6), 0); }#endif /* Invalid PAL call */
@@ -3079,9 +3081,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) ret =gen_bcond (ctx,TCG_COND_GT , ra, disp21,0 );break ; invalid_opc: -gen_invalid (ctx); -/* PC updated by gen_excp. */ - ret =EXIT_PC_UPDATED ; + ret =gen_invalid (ctx);break ; }
@@ -3185,6 +3185,7 @@ static inline void gen_intermediate_code_internal(CPUState *env,switch (ret) {case EXIT_GOTO_TB : +case EXIT_NORETURN :break ;case EXIT_PC_STALE :tcg_gen_movi_i64 (cpu_pc, ctx.pc);
Signature · 1 line
1.6.2.5
PATCH 8/10 target-alpha: Fix load-locked/store-conditional.
In reply to Richard HendersonUse an exception plus start_exclusive to implement the compare-and-swap. This follows the example set by the MIPS and PPC ports.
--- linux-user/main.c | 55 +++++++++++++ target-alpha/cpu.h | 6 +- target-alpha/helper.c | 7 +- target-alpha/op_helper.c | 2 + target-alpha/translate.c | 202 ++++++++++++++++++++++++++++----------------- 5 files changed, 193 insertions(+), 79 deletions(-)
linux-user/main.c +55 -0
@@ -2348,6 +2348,51 @@ void cpu_loop(CPUM68KState *env)#endif /* TARGET_M68K */ #ifdef TARGET_ALPHA +static void do_store_exclusive (CPUAlphaState *env,int reg,int quad) +{ +target_ulong addr, val, tmp; +target_siginfo_t info; +int ret =0 ; + + addr = env->lock_addr; + tmp = env->lock_st_addr; + env->lock_addr =-1 ; + env->lock_st_addr =0 ; + +start_exclusive (); +mmap_lock (); + +if (addr == tmp) { +if (quad ?get_user_s64 (val, addr) :get_user_s32 (val, addr)) { + goto do_sigsegv; + } + +if (val == env->lock_value) { + tmp = env->ir[reg]; +if (quad ?put_user_u64 (tmp, addr) :put_user_u32 (tmp, addr)) { + goto do_sigsegv; + } + ret =1 ; + } + } + env->ir[reg] = ret; + env->pc +=4 ; + +mmap_unlock (); +end_exclusive (); +return ; + + do_sigsegv: +mmap_unlock (); +end_exclusive (); + + info.si_signo =TARGET_SIGSEGV ; + info.si_errno =0 ; + info.si_code =TARGET_SEGV_MAPERR ; + info._sifields._sigfault._addr = addr; +queue_signal (env,TARGET_SIGSEGV , &info); +} +void cpu_loop (CPUState *env) {int trapnr;
@@ -2372,6 +2417,7 @@ void cpu_loop (CPUState *env)exit (1 );break ;case EXCP_ARITH : + env->lock_addr =-1 ; info.si_signo =TARGET_SIGFPE ; info.si_errno =0 ; info.si_code =TARGET_FPE_FLTINV ;
@@ -2383,6 +2429,7 @@ void cpu_loop (CPUState *env)exit (1 );break ;case EXCP_DFAULT : + env->lock_addr =-1 ; info.si_signo =TARGET_SIGSEGV ; info.si_errno =0 ; info.si_code =0 ;/* ??? SEGV_MAPERR vs SEGV_ACCERR. */
@@ -2406,6 +2453,7 @@ void cpu_loop (CPUState *env)exit (1 );break ;case EXCP_UNALIGN : + env->lock_addr =-1 ; info.si_signo =TARGET_SIGBUS ; info.si_errno =0 ; info.si_code =TARGET_BUS_ADRALN ;
@@ -2414,6 +2462,7 @@ void cpu_loop (CPUState *env)break ;case EXCP_OPCDEC : do_sigill: + env->lock_addr =-1 ; info.si_signo =TARGET_SIGILL ; info.si_errno =0 ; info.si_code =TARGET_ILL_ILLOPC ;
@@ -2424,6 +2473,7 @@ void cpu_loop (CPUState *env)/* No-op. Linux simply re-enables the FPU. */ break ; case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1): + env->lock_addr =-1 ;switch ((trapnr >>6 ) |0x80 ) {case 0x80 :/* BPT */
@@ -2513,11 +2563,16 @@ void cpu_loop (CPUState *env)case EXCP_DEBUG : info.si_signo =gdb_handlesig (env,TARGET_SIGTRAP );if (info.si_signo) { + env->lock_addr =-1 ; info.si_errno =0 ; info.si_code =TARGET_TRAP_BRKPT ;queue_signal (env, info.si_signo, &info); }break ; +case EXCP_STL_C : +case EXCP_STQ_C : +do_store_exclusive (env, env->error_code, trapnr -EXCP_STL_C ); +break ;default :printf ("Unhandled trap: 0x%x\n" , trapnr);cpu_dump_state (env, stderr, fprintf,0 );
target-alpha/cpu.h +5 -1
@@ -355,11 +355,13 @@ struct CPUAlphaState {uint64_t ir[31 ];float64 fir[31 ];uint64_t pc; -uint64_t lock;uint32_t pcc[2 ];uint64_t ipr[IPR_LAST ];uint64_t ps;uint64_t unique; +uint64_t lock_addr; +uint64_t lock_st_addr; +uint64_t lock_value;float_status fp_status;/* The following fields make up the FPCR, but in FP_STATUS format. */ uint8_t fpcr_exc_status;
@@ -440,6 +442,8 @@ enum {/* Pseudo exception for console */ EXCP_CONSOLE_DISPATCH =0x4001 ,EXCP_CONSOLE_FIXUP =0x4002 , +EXCP_STL_C =0x4003 , + EXCP_STQ_C = 0x4004, };/* Arithmetic exception */
target-alpha/helper.c +5 -2
@@ -556,12 +556,15 @@ void cpu_dump_state (CPUState *env, FILE *f,if ((i %3 ) ==2 )cpu_fprintf (f,"\n" ); } -cpu_fprintf (f,"\n" ); + +cpu_fprintf (f,"lock_a " TARGET_FMT_lx" lock_v " TARGET_FMT_lx"\n" , + env->lock_addr, env->lock_value); +for (i =0 ; i <31 ; i++) {cpu_fprintf (f,"FIR%02d " TARGET_FMT_lx" " , i, *((uint64_t *)(&env->fir[i])));if ((i %3 ) ==2 )cpu_fprintf (f,"\n" ); } -cpu_fprintf (f,"\nlock " TARGET_FMT_lx"\n" , env->lock); +cpu_fprintf (f,"\n" ); }
target-alpha/op_helper.c +2 -0
@@ -1159,6 +1159,7 @@ void helper_hw_rei (void) env->pc = env->ipr[IPR_EXC_ADDR ] & ~3 ; env->ipr[IPR_EXC_ADDR ] = env->ipr[IPR_EXC_ADDR ] &1 ; env->intr_flag =0 ; + env->lock_addr =-1 ;/* XXX: re-enable interrupts and memory mapping */ }
@@ -1167,6 +1168,7 @@ void helper_hw_ret (uint64_t a) env->pc = a & ~3 ; env->ipr[IPR_EXC_ADDR ] = a &1 ; env->intr_flag =0 ; + env->lock_addr =-1 ;/* XXX: re-enable interrupts and memory mapping */ }
target-alpha/translate.c +126 -76
312 lines not on this page · raw message
Signature · 1 line
1.6.2.5
PATCH 9/10 target-alpha: Implement RPCC.
In reply to Richard HendersonA minimal implementation that more or less corresponds to the user-level version used by target-i386. More hoops will want to be jumped through when alpha gets system-level emulation.
--- target-alpha/cpu.h | 1 - target-alpha/op_helper.c | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-)
target-alpha/cpu.h +0 -1
@@ -355,7 +355,6 @@ struct CPUAlphaState {uint64_t ir[31 ];float64 fir[31 ];uint64_t pc; -uint32_t pcc[2 ];uint64_t ipr[IPR_LAST ];uint64_t ps;uint64_t unique;
target-alpha/op_helper.c +3 -2
@@ -21,6 +21,7 @@#include "host-utils.h" #include "softfloat.h" #include "helper.h" +#include "qemu-timer.h" /*****************************************************************************/ /* Exceptions processing helpers */
@@ -33,8 +34,8 @@ void QEMU_NORETURN helper_excp (int excp, int error)uint64_t helper_load_pcc (void ) { -/* XXX: TODO */ -return 0 ; +/* ??? This isn't a timer for which we have any rate info. */ +return (uint32_t )cpu_get_real_ticks (); }uint64_t helper_load_fpcr (void )
Signature · 1 line
1.6.2.5
PATCH 10/10 Implement cpu_get_real_ticks for Alpha.
In reply to Richard Henderson--- qemu-timer.h | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)
qemu-timer.h +13 -0
@@ -209,6 +209,19 @@ static inline int64_t cpu_get_real_ticks(void) return (int64_t)(count * cyc_per_count); } +#elif defined(__alpha__) + +static inline int64_t cpu_get_real_ticks (void ) +{ +uint64_t cc; +uint32_t cur, ofs; + + asmvolatile ("rpcc %0" :"=r" (cc)); + cur = cc; + ofs = cc >>32 ; +return cur - ofs; +} +#else /* The host CPU doesn't have an easily accessible cycle counter. Just return a monotonically increasing value. This will be
Signature · 1 line
1.6.2.5