diff --git a/.gitignore b/.gitignore index 1219e4a..b26b31c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/valgrind-3.18.1.tar.bz2 +SOURCES/valgrind-3.19.0.tar.bz2 diff --git a/.valgrind.metadata b/.valgrind.metadata index 92f2922..aad2930 100644 --- a/.valgrind.metadata +++ b/.valgrind.metadata @@ -1 +1 @@ -0a694a8d0c2152978bf64b67ad0b3dd972bbeb54 SOURCES/valgrind-3.18.1.tar.bz2 +294c341b421b4d9534e42e8125f509c148f48c17 SOURCES/valgrind-3.19.0.tar.bz2 diff --git a/SOURCES/valgrind-3.18.1-amd64-more-spec-rules.patch b/SOURCES/valgrind-3.18.1-amd64-more-spec-rules.patch deleted file mode 100644 index 87794ee..0000000 --- a/SOURCES/valgrind-3.18.1-amd64-more-spec-rules.patch +++ /dev/null @@ -1,105 +0,0 @@ -commit 595341b150312d2407bd43304449bf39ec3e1fa8 -Author: Julian Seward -Date: Sat Nov 13 19:59:07 2021 +0100 - - amd64 front end: add more spec rules: - - S after SHRQ - Z after SHLQ - NZ after SHLQ - Z after SHLL - S after SHLL - - The lack of at least one of these was observed to cause occasional false - positives in Memcheck. - - Plus add commented-out cases so as to complete the set of 12 rules - {Z,NZ,S,NS} after {SHRQ,SHLQ,SHLL}. The commented-out ones are commented - out because I so far didn't find any use cases for them. - -diff --git a/VEX/priv/guest_amd64_helpers.c b/VEX/priv/guest_amd64_helpers.c -index 9d61e7a0f..ba71c1b62 100644 ---- a/VEX/priv/guest_amd64_helpers.c -+++ b/VEX/priv/guest_amd64_helpers.c -@@ -1823,16 +1823,26 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, - /*---------------- SHRQ ----------------*/ - - if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondZ)) { -- /* SHRQ, then Z --> test dep1 == 0 */ -+ /* SHRQ, then Z --> test result[63:0] == 0 */ - return unop(Iop_1Uto64, - binop(Iop_CmpEQ64, cc_dep1, mkU64(0))); - } - if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondNZ)) { -- /* SHRQ, then NZ --> test dep1 != 0 */ -+ /* SHRQ, then NZ --> test result[63:0] != 0 */ - return unop(Iop_1Uto64, - binop(Iop_CmpNE64, cc_dep1, mkU64(0))); - } - -+ if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondS)) { -+ /* SHRQ, then S --> (ULong)result[63] (result is in dep1) */ -+ return binop(Iop_Shr64, cc_dep1, mkU8(63)); -+ } -+ // No known test case for this, hence disabled: -+ //if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondNS)) { -+ // /* SHRQ, then NS --> (ULong) ~ result[63] */ -+ // vassert(0); -+ //} -+ - /*---------------- SHRL ----------------*/ - - if (isU64(cc_op, AMD64G_CC_OP_SHRL) && isU64(cond, AMD64CondZ)) { -@@ -1881,6 +1891,52 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name, - // mkU32(0))); - //} - -+ /*---------------- SHLQ ----------------*/ -+ -+ if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondZ)) { -+ /* SHLQ, then Z --> test dep1 == 0 */ -+ return unop(Iop_1Uto64, -+ binop(Iop_CmpEQ64, cc_dep1, mkU64(0))); -+ } -+ if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondNZ)) { -+ /* SHLQ, then NZ --> test dep1 != 0 */ -+ return unop(Iop_1Uto64, -+ binop(Iop_CmpNE64, cc_dep1, mkU64(0))); -+ } -+ -+ //if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondS)) { -+ // /* SHLQ, then S --> (ULong)result[63] */ -+ // vassert(0); -+ //} -+ //if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondNS)) { -+ // /* SHLQ, then NS --> (ULong) ~ result[63] */ -+ // vassert(0); -+ //} -+ -+ /*---------------- SHLL ----------------*/ -+ -+ if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondZ)) { -+ /* SHLL, then Z --> test result[31:0] == 0 */ -+ return unop(Iop_1Uto64, -+ binop(Iop_CmpEQ32, unop(Iop_64to32, cc_dep1), -+ mkU32(0))); -+ } -+ //if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNZ)) { -+ // /* SHLL, then NZ --> test dep1 != 0 */ -+ // vassert(0); -+ //} -+ -+ if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondS)) { -+ /* SHLL, then S --> (ULong)result[31] */ -+ return binop(Iop_And64, -+ binop(Iop_Shr64, cc_dep1, mkU8(31)), -+ mkU64(1)); -+ } -+ //if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNS)) { -+ // /* SHLL, then NS --> (ULong) ~ result[31] */ -+ // vassert(0); -+ //} -+ - /*---------------- COPY ----------------*/ - /* This can happen, as a result of amd64 FP compares: "comisd ... ; - jbe" for example. */ diff --git a/SOURCES/valgrind-3.18.1-arm64-atomic-align.patch b/SOURCES/valgrind-3.18.1-arm64-atomic-align.patch deleted file mode 100644 index 8cce35f..0000000 --- a/SOURCES/valgrind-3.18.1-arm64-atomic-align.patch +++ /dev/null @@ -1,163 +0,0 @@ -commit 2be719921e700a9ac9b85f470ed87cb8adf8151b -Author: Julian Seward -Date: Sat Nov 13 09:27:01 2021 +0100 - - Bug 445415 - arm64 front end: alignment checks missing for atomic instructions. - - For the arm64 front end, none of the atomic instructions have address - alignment checks included in their IR. They all should. The effect of - missing alignment checks in the IR is that, since this IR will in most cases - be translated back to atomic instructions in the back end, we will get - alignment traps (SIGBUS) on the host side and not on the guest side, which is - (very) incorrect behaviour of the simulation. - - -diff --git a/VEX/priv/guest_arm64_toIR.c b/VEX/priv/guest_arm64_toIR.c -index ee018c6a9..16a7e075f 100644 ---- a/VEX/priv/guest_arm64_toIR.c -+++ b/VEX/priv/guest_arm64_toIR.c -@@ -4833,6 +4833,34 @@ static IRTemp gen_zwidening_load ( UInt szB, IRTemp addr ) - } - - -+/* Generate a SIGBUS followed by a restart of the current instruction if -+ `effective_addr` is `align`-aligned. This is required behaviour for atomic -+ instructions. This assumes that guest_RIP_curr_instr is set correctly! -+ -+ This is hardwired to generate SIGBUS because so far the only supported arm64 -+ (arm64-linux) does that. Should we need to later extend it to generate some -+ other signal, use the same scheme as with gen_SIGNAL_if_not_XX_aligned in -+ guest_amd64_toIR.c. */ -+static -+void gen_SIGBUS_if_not_XX_aligned ( IRTemp effective_addr, ULong align ) -+{ -+ if (align == 1) { -+ return; -+ } -+ vassert(align == 16 || align == 8 || align == 4 || align == 2); -+ stmt( -+ IRStmt_Exit( -+ binop(Iop_CmpNE64, -+ binop(Iop_And64,mkexpr(effective_addr),mkU64(align-1)), -+ mkU64(0)), -+ Ijk_SigBUS, -+ IRConst_U64(guest_PC_curr_instr), -+ OFFB_PC -+ ) -+ ); -+} -+ -+ - /* Generate a "standard 7" name, from bitQ and size. But also - allow ".1d" since that's occasionally useful. */ - static -@@ -6670,7 +6698,7 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - - IRTemp ea = newTemp(Ity_I64); - assign(ea, getIReg64orSP(nn)); -- /* FIXME generate check that ea is szB-aligned */ -+ gen_SIGBUS_if_not_XX_aligned(ea, szB); - - if (isLD && ss == BITS5(1,1,1,1,1)) { - IRTemp res = newTemp(ty); -@@ -6803,7 +6831,7 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - - IRTemp ea = newTemp(Ity_I64); - assign(ea, getIReg64orSP(nn)); -- /* FIXME generate check that ea is 2*elemSzB-aligned */ -+ gen_SIGBUS_if_not_XX_aligned(ea, fullSzB); - - if (isLD && ss == BITS5(1,1,1,1,1)) { - if (abiinfo->guest__use_fallback_LLSC) { -@@ -7044,7 +7072,7 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - - IRTemp ea = newTemp(Ity_I64); - assign(ea, getIReg64orSP(nn)); -- /* FIXME generate check that ea is szB-aligned */ -+ gen_SIGBUS_if_not_XX_aligned(ea, szB); - - if (isLD) { - IRTemp res = newTemp(ty); -@@ -7159,6 +7187,7 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - - IRTemp ea = newTemp(Ity_I64); - assign(ea, getIReg64orSP(nn)); -+ gen_SIGBUS_if_not_XX_aligned(ea, szB); - - // Insert barrier before loading for acquire and acquire-release variants: - // A and AL. -@@ -7266,6 +7295,10 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - IRType ty = integerIRTypeOfSize(szB); - Bool is64 = szB == 8; - -+ IRTemp ea = newTemp(Ity_I64); -+ assign(ea, getIReg64orSP(nn)); -+ gen_SIGBUS_if_not_XX_aligned(ea, szB); -+ - IRExpr *exp = narrowFrom64(ty, getIReg64orZR(ss)); - IRExpr *new = narrowFrom64(ty, getIReg64orZR(tt)); - -@@ -7275,7 +7308,7 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - // Store the result back if LHS remains unchanged in memory. - IRTemp old = newTemp(ty); - stmt( IRStmt_CAS(mkIRCAS(/*oldHi*/IRTemp_INVALID, old, -- Iend_LE, getIReg64orSP(nn), -+ Iend_LE, mkexpr(ea), - /*expdHi*/NULL, exp, - /*dataHi*/NULL, new)) ); - -@@ -7307,6 +7340,10 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - if ((ss & 0x1) || (tt & 0x1)) { - /* undefined; fall through */ - } else { -+ IRTemp ea = newTemp(Ity_I64); -+ assign(ea, getIReg64orSP(nn)); -+ gen_SIGBUS_if_not_XX_aligned(ea, is64 ? 16 : 8); -+ - IRExpr *expLo = getIRegOrZR(is64, ss); - IRExpr *expHi = getIRegOrZR(is64, ss + 1); - IRExpr *newLo = getIRegOrZR(is64, tt); -@@ -7318,7 +7355,7 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - stmt(IRStmt_MBE(Imbe_Fence)); - - stmt( IRStmt_CAS(mkIRCAS(oldHi, oldLo, -- Iend_LE, getIReg64orSP(nn), -+ Iend_LE, mkexpr(ea), - expHi, expLo, - newHi, newLo)) ); - -diff --git a/VEX/priv/host_arm64_defs.c b/VEX/priv/host_arm64_defs.c -index b65e27db4..39c6aaa46 100644 ---- a/VEX/priv/host_arm64_defs.c -+++ b/VEX/priv/host_arm64_defs.c -@@ -4033,6 +4033,7 @@ Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc, - case Ijk_FlushDCache: trcval = VEX_TRC_JMP_FLUSHDCACHE; break; - case Ijk_NoRedir: trcval = VEX_TRC_JMP_NOREDIR; break; - case Ijk_SigTRAP: trcval = VEX_TRC_JMP_SIGTRAP; break; -+ case Ijk_SigBUS: trcval = VEX_TRC_JMP_SIGBUS; break; - //case Ijk_SigSEGV: trcval = VEX_TRC_JMP_SIGSEGV; break; - case Ijk_Boring: trcval = VEX_TRC_JMP_BORING; break; - /* We don't expect to see the following being assisted. */ -diff --git a/VEX/priv/host_arm64_isel.c b/VEX/priv/host_arm64_isel.c -index 094e7e74b..82cb2d78c 100644 ---- a/VEX/priv/host_arm64_isel.c -+++ b/VEX/priv/host_arm64_isel.c -@@ -4483,6 +4483,7 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) - case Ijk_InvalICache: - case Ijk_FlushDCache: - case Ijk_SigTRAP: -+ case Ijk_SigBUS: - case Ijk_Yield: { - HReg r = iselIntExpr_R(env, IRExpr_Const(stmt->Ist.Exit.dst)); - addInstr(env, ARM64Instr_XAssisted(r, amPC, cc, -@@ -4576,8 +4577,8 @@ static void iselNext ( ISelEnv* env, - case Ijk_InvalICache: - case Ijk_FlushDCache: - case Ijk_SigTRAP: -- case Ijk_Yield: -- { -+ case Ijk_SigBUS: -+ case Ijk_Yield: { - HReg r = iselIntExpr_R(env, next); - ARM64AMode* amPC = mk_baseblock_64bit_access_amode(offsIP); - addInstr(env, ARM64Instr_XAssisted(r, amPC, ARM64cc_AL, jk)); diff --git a/SOURCES/valgrind-3.18.1-arm64-atomics-rdm.patch b/SOURCES/valgrind-3.18.1-arm64-atomics-rdm.patch deleted file mode 100644 index 47cb91a..0000000 --- a/SOURCES/valgrind-3.18.1-arm64-atomics-rdm.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/VEX/priv/main_main.c b/VEX/priv/main_main.c -index 1253cf588..482047c7a 100644 ---- a/VEX/priv/main_main.c -+++ b/VEX/priv/main_main.c -@@ -2163,11 +2163,6 @@ static void check_hwcaps ( VexArch arch, UInt hwcaps ) - if (have_fp16 != have_vfp16) - invalid_hwcaps(arch, hwcaps, - "Mismatch detected between scalar and vector FP16 features.\n"); -- Bool have_rdm = ((hwcaps & VEX_HWCAPS_ARM64_RDM) != 0); -- Bool have_atomics = ((hwcaps & VEX_HWCAPS_ARM64_ATOMICS) != 0); -- if (have_rdm != have_atomics) -- invalid_hwcaps(arch, hwcaps, -- "Mismatch detected between RDMA and atomics features.\n"); - return; - } - diff --git a/SOURCES/valgrind-3.18.1-arm64-doubleword-cas.patch b/SOURCES/valgrind-3.18.1-arm64-doubleword-cas.patch deleted file mode 100644 index 7cf0bf5..0000000 --- a/SOURCES/valgrind-3.18.1-arm64-doubleword-cas.patch +++ /dev/null @@ -1,121 +0,0 @@ -commit 7dbe2fed72886874f2eaf57dc07929542ae55b58 -Author: Julian Seward -Date: Fri Nov 12 10:40:48 2021 +0100 - - Bug 445354 - arm64 backend: incorrect code emitted for doubleword CAS. - - The sequence of instructions emitted by the arm64 backend for doubleword - compare-and-swap is incorrect. This could lead to incorrect simulation of the - AArch8.1 atomic instructions (CASP, at least). It also causes failures in the - upcoming fix for v8.0 support for LD{,A}XP/ST{,L}XP in bug 444399, at least - when running with the fallback LL/SC implementation - (`--sim-hints=fallback-llsc`, or as autoselected at startup). In the worst - case it can cause segfaulting in the generated code, because it could jump - backwards unexpectedly far. - - The problem is the sequence emitted for ARM64in_CASP: - - * the jump offsets are incorrect, both for `bne out` (x 2) and `cbnz w1, loop`. - - * using w1 to hold the success indication of the stxp instruction trashes the - previous value in x1. But the value in x1 is an output of ARM64in_CASP, - hence one of the two output registers is corrupted. That confuses any code - downstream that want to inspect those values to find out whether or not the - transaction succeeded. - - The fixes are to - - * fix the branch offsets - - * use a different register to hold the stxp success indication. w3 is a - convenient check. - -diff --git a/VEX/priv/host_arm64_defs.c b/VEX/priv/host_arm64_defs.c -index 5dccc0495..5657bcab9 100644 ---- a/VEX/priv/host_arm64_defs.c -+++ b/VEX/priv/host_arm64_defs.c -@@ -2271,6 +2271,7 @@ void getRegUsage_ARM64Instr ( HRegUsage* u, const ARM64Instr* i, Bool mode64 ) - addHRegUse(u, HRmWrite, hregARM64_X1()); - addHRegUse(u, HRmWrite, hregARM64_X9()); - addHRegUse(u, HRmWrite, hregARM64_X8()); -+ addHRegUse(u, HRmWrite, hregARM64_X3()); - break; - case ARM64in_MFence: - return; -@@ -4254,16 +4255,16 @@ Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc, - - -- always: - cmp x0, x8 // EB08001F -- bne out // 540000E1 (b.ne #28 ) -+ bne out // 540000A1 - cmp x1, x9 // EB09003F -- bne out // 540000A1 (b.ne #20 ) -+ bne out // 54000061 - - -- one of: -- stxp w1, x6, x7, [x2] // C8211C46 -- stxp w1, w6, w7, [x2] // 88211C46 -+ stxp w3, x6, x7, [x2] // C8231C46 -+ stxp w3, w6, w7, [x2] // 88231C46 - - -- always: -- cbnz w1, loop // 35FFFE81 (cbnz w1, #-48 ) -+ cbnz w3, loop // 35FFFF03 - out: - */ - switch (i->ARM64in.CASP.szB) { -@@ -4277,15 +4278,15 @@ Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc, - default: vassert(0); - } - *p++ = 0xEB08001F; -- *p++ = 0x540000E1; -- *p++ = 0xEB09003F; - *p++ = 0x540000A1; -+ *p++ = 0xEB09003F; -+ *p++ = 0x54000061; - switch (i->ARM64in.CASP.szB) { -- case 8: *p++ = 0xC8211C46; break; -- case 4: *p++ = 0x88211C46; break; -+ case 8: *p++ = 0xC8231C46; break; -+ case 4: *p++ = 0x88231C46; break; - default: vassert(0); - } -- *p++ = 0x35FFFE81; -+ *p++ = 0x35FFFF03; - goto done; - } - case ARM64in_MFence: { -diff --git a/VEX/priv/host_arm64_defs.h b/VEX/priv/host_arm64_defs.h -index f0737f2c6..01fb5708e 100644 ---- a/VEX/priv/host_arm64_defs.h -+++ b/VEX/priv/host_arm64_defs.h -@@ -720,6 +720,7 @@ typedef - Int szB; /* 1, 2, 4 or 8 */ - } StrEX; - /* x1 = CAS(x3(addr), x5(expected) -> x7(new)), -+ and trashes x8 - where x1[8*szB-1 : 0] == x5[8*szB-1 : 0] indicates success, - x1[8*szB-1 : 0] != x5[8*szB-1 : 0] indicates failure. - Uses x8 as scratch (but that's not allocatable). -@@ -738,7 +739,7 @@ typedef - -- if branch taken, failure; x1[[8*szB-1 : 0] holds old value - -- attempt to store - stxr w8, x7, [x3] -- -- if store successful, x1==0, so the eor is "x1 := x5" -+ -- if store successful, x8==0 - -- if store failed, branch back and try again. - cbne w8, loop - after: -@@ -746,6 +747,12 @@ typedef - struct { - Int szB; /* 1, 2, 4 or 8 */ - } CAS; -+ /* Doubleworld CAS, 2 x 32 bit or 2 x 64 bit -+ x0(oldLSW),x1(oldMSW) -+ = DCAS(x2(addr), x4(expectedLSW),x5(expectedMSW) -+ -> x6(newLSW),x7(newMSW)) -+ and trashes x8, x9 and x3 -+ */ - struct { - Int szB; /* 4 or 8 */ - } CASP; diff --git a/SOURCES/valgrind-3.18.1-arm64-ldaxp-stlxp.patch b/SOURCES/valgrind-3.18.1-arm64-ldaxp-stlxp.patch deleted file mode 100644 index d118cc6..0000000 --- a/SOURCES/valgrind-3.18.1-arm64-ldaxp-stlxp.patch +++ /dev/null @@ -1,1440 +0,0 @@ -commit 530df882b8f60ecacaf2b9b8a719f7ea1c1d1650 -Author: Julian Seward -Date: Fri Nov 12 12:13:45 2021 +0100 - - Bug 444399 - disInstr(arm64): unhandled instruction 0xC87F2D89 (LD{,A}XP and ST{,L}XP). - - This is unfortunately a big and complex patch, to implement LD{,A}XP and - ST{,L}XP. These were omitted from the original AArch64 v8.0 implementation - for unknown reasons. - - (Background) the patch is made significantly more complex because for AArch64 - we actually have two implementations of the underlying - Load-Linked/Store-Conditional (LL/SC) machinery: a "primary" implementation, - which translates LL/SC more or less directly into IR and re-emits them at the - back end, and a "fallback" implementation that implements LL/SC "manually", by - taking advantage of the fact that V serialises thread execution, so we can - "implement" LL/SC by simulating a reservation using fields LLSC_* in the guest - state, and invalidating the reservation at every thread switch. - - (Background) the fallback scheme is needed because the primary scheme is in - violation of the ARMv8 semantics in that it can (easily) introduce extra - memory references between the LL and SC, hence on some hardware causing the - reservation to always fail and so the simulated program to wind up looping - forever. - - For these instructions, big picture: - - * for the primary implementation, we take advantage of the fact that - IRStmt_LLSC allows I128 bit transactions to be represented. Hence we bundle - up the two 64-bit data elements into an I128 (or vice versa) and present a - single I128-typed IRStmt_LLSC in the IR. In the backend, those are - re-emitted as LDXP/STXP respectively. For LL/SC on 32-bit register pairs, - that bundling produces a single 64-bit item, and so the existing LL/SC - backend machinery handles it. The effect is that a doubleword 32-bit LL/SC - in the front end translates into a single 64-bit LL/SC in the back end. - Overall, though, the implementation is straightforward. - - * for the fallback implementation, it is necessary to extend the guest state - field `guest_LLSC_DATA` to represent a 128-bit transaction, by splitting it - into _DATA_LO64 and DATA_HI64. Then, the implementation is an exact - analogue of the fallback implementation for single-word LL/SC. It takes - advantage of the fact that the backend already supports 128-bit CAS, as - fixed in bug 445354. As with the primary implementation, doubleword 32-bit - LL/SC is bundled into a single 64-bit transaction. - - Detailed changes: - - * new arm64 guest state fields LLSC_DATA_LO64/LLSC_DATA_LO64 to replace - guest_LLSC_DATA - - * (ridealong fix) arm64 front end: a fix to a minor and harmless decoding bug - for the single-word LDX/STX case. - - * arm64 front end: IR generation for LD{,A}XP/ST{,L}XP: tedious and - longwinded, but per comments above, an exact(ish) analogue of the singleword - case - - * arm64 backend: new insns ARM64Instr_LdrEXP / ARM64Instr_StrEXP to wrap up 2 - x 64 exclusive loads/stores. Per comments above, there's no need to handle - the 2 x 32 case. - - * arm64 isel: translate I128-typed IRStmt_LLSC into the above two insns - - * arm64 isel: some auxiliary bits and pieces needed to handle I128 values; - this is standard doubleword isel stuff - - * arm64 isel: (ridealong fix): Ist_CAS: check for endianness of the CAS! - - * arm64 isel: (ridealong) a couple of formatting fixes - - * IR infrastructure: add support for I128 constants, done the same as V128 - constants - - * memcheck: handle shadow loads and stores for I128 values - - * testcase: memcheck/tests/atomic_incs.c: on arm64, also test 128-bit atomic - addition, to check we really have atomicity right - - * testcase: new test none/tests/arm64/ldxp_stxp.c, tests operation but not - atomicity. (Smoke test). - -diff --git a/VEX/priv/guest_arm64_toIR.c b/VEX/priv/guest_arm64_toIR.c -index 12a1c5978..ee018c6a9 100644 ---- a/VEX/priv/guest_arm64_toIR.c -+++ b/VEX/priv/guest_arm64_toIR.c -@@ -1184,9 +1184,10 @@ static IRExpr* narrowFrom64 ( IRType dstTy, IRExpr* e ) - #define OFFB_CMSTART offsetof(VexGuestARM64State,guest_CMSTART) - #define OFFB_CMLEN offsetof(VexGuestARM64State,guest_CMLEN) - --#define OFFB_LLSC_SIZE offsetof(VexGuestARM64State,guest_LLSC_SIZE) --#define OFFB_LLSC_ADDR offsetof(VexGuestARM64State,guest_LLSC_ADDR) --#define OFFB_LLSC_DATA offsetof(VexGuestARM64State,guest_LLSC_DATA) -+#define OFFB_LLSC_SIZE offsetof(VexGuestARM64State,guest_LLSC_SIZE) -+#define OFFB_LLSC_ADDR offsetof(VexGuestARM64State,guest_LLSC_ADDR) -+#define OFFB_LLSC_DATA_LO64 offsetof(VexGuestARM64State,guest_LLSC_DATA_LO64) -+#define OFFB_LLSC_DATA_HI64 offsetof(VexGuestARM64State,guest_LLSC_DATA_HI64) - - - /* ---------------- Integer registers ---------------- */ -@@ -6652,7 +6653,7 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - (coregrind/m_scheduler/scheduler.c, run_thread_for_a_while() - has to do this bit) - */ -- if (INSN(29,23) == BITS7(0,0,1,0,0,0,0) -+ if (INSN(29,24) == BITS6(0,0,1,0,0,0) - && (INSN(23,21) & BITS3(1,0,1)) == BITS3(0,0,0) - && INSN(14,10) == BITS5(1,1,1,1,1)) { - UInt szBlg2 = INSN(31,30); -@@ -6678,7 +6679,8 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - // if it faults. - IRTemp loaded_data64 = newTemp(Ity_I64); - assign(loaded_data64, widenUto64(ty, loadLE(ty, mkexpr(ea)))); -- stmt( IRStmt_Put( OFFB_LLSC_DATA, mkexpr(loaded_data64) )); -+ stmt( IRStmt_Put( OFFB_LLSC_DATA_LO64, mkexpr(loaded_data64) )); -+ stmt( IRStmt_Put( OFFB_LLSC_DATA_HI64, mkU64(0) )); - stmt( IRStmt_Put( OFFB_LLSC_ADDR, mkexpr(ea) )); - stmt( IRStmt_Put( OFFB_LLSC_SIZE, mkU64(szB) )); - putIReg64orZR(tt, mkexpr(loaded_data64)); -@@ -6729,7 +6731,7 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - )); - // Fail if the data doesn't match the LL data - IRTemp llsc_data64 = newTemp(Ity_I64); -- assign(llsc_data64, IRExpr_Get(OFFB_LLSC_DATA, Ity_I64)); -+ assign(llsc_data64, IRExpr_Get(OFFB_LLSC_DATA_LO64, Ity_I64)); - stmt( IRStmt_Exit( - binop(Iop_CmpNE64, widenUto64(ty, loadLE(ty, mkexpr(ea))), - mkexpr(llsc_data64)), -@@ -6771,6 +6773,257 @@ Bool dis_ARM64_load_store(/*MB_OUT*/DisResult* dres, UInt insn, - /* else fall through */ - } - -+ /* -------------------- LD{,A}XP -------------------- */ -+ /* -------------------- ST{,L}XP -------------------- */ -+ /* 31 30 29 23 20 15 14 9 4 -+ 1 sz 001000 011 11111 0 t2 n t1 LDXP Rt1, Rt2, [Xn|SP] -+ 1 sz 001000 011 11111 1 t2 n t1 LDAXP Rt1, Rt2, [Xn|SP] -+ 1 sz 001000 001 s 0 t2 n t1 STXP Ws, Rt1, Rt2, [Xn|SP] -+ 1 sz 001000 001 s 1 t2 n t1 STLXP Ws, Rt1, Rt2, [Xn|SP] -+ */ -+ /* See just above, "LD{,A}X{R,RH,RB} / ST{,L}X{R,RH,RB}", for detailed -+ comments about this implementation. Note the 'sz' field here is only 1 -+ bit; above, it is 2 bits, and has a different encoding. -+ */ -+ if (INSN(31,31) == 1 -+ && INSN(29,24) == BITS6(0,0,1,0,0,0) -+ && (INSN(23,21) & BITS3(1,0,1)) == BITS3(0,0,1)) { -+ Bool elemIs64 = INSN(30,30) == 1; -+ Bool isLD = INSN(22,22) == 1; -+ Bool isAcqOrRel = INSN(15,15) == 1; -+ UInt ss = INSN(20,16); -+ UInt tt2 = INSN(14,10); -+ UInt nn = INSN(9,5); -+ UInt tt1 = INSN(4,0); -+ -+ UInt elemSzB = elemIs64 ? 8 : 4; -+ UInt fullSzB = 2 * elemSzB; -+ IRType elemTy = integerIRTypeOfSize(elemSzB); -+ IRType fullTy = integerIRTypeOfSize(fullSzB); -+ -+ IRTemp ea = newTemp(Ity_I64); -+ assign(ea, getIReg64orSP(nn)); -+ /* FIXME generate check that ea is 2*elemSzB-aligned */ -+ -+ if (isLD && ss == BITS5(1,1,1,1,1)) { -+ if (abiinfo->guest__use_fallback_LLSC) { -+ // Fallback implementation of LL. -+ // Do the load first so we don't update any guest state if it -+ // faults. Assumes little-endian guest. -+ if (fullTy == Ity_I64) { -+ vassert(elemSzB == 4); -+ IRTemp loaded_data64 = newTemp(Ity_I64); -+ assign(loaded_data64, loadLE(fullTy, mkexpr(ea))); -+ stmt( IRStmt_Put( OFFB_LLSC_DATA_LO64, mkexpr(loaded_data64) )); -+ stmt( IRStmt_Put( OFFB_LLSC_DATA_HI64, mkU64(0) )); -+ stmt( IRStmt_Put( OFFB_LLSC_ADDR, mkexpr(ea) )); -+ stmt( IRStmt_Put( OFFB_LLSC_SIZE, mkU64(8) )); -+ putIReg64orZR(tt1, unop(Iop_32Uto64, -+ unop(Iop_64to32, -+ mkexpr(loaded_data64)))); -+ putIReg64orZR(tt2, unop(Iop_32Uto64, -+ unop(Iop_64HIto32, -+ mkexpr(loaded_data64)))); -+ } else { -+ vassert(elemSzB == 8 && fullTy == Ity_I128); -+ IRTemp loaded_data128 = newTemp(Ity_I128); -+ // Hack: do the load as V128 rather than I128 so as to avoid -+ // having to implement I128 loads in the arm64 back end. -+ assign(loaded_data128, unop(Iop_ReinterpV128asI128, -+ loadLE(Ity_V128, mkexpr(ea)))); -+ IRTemp loaded_data_lo64 = newTemp(Ity_I64); -+ IRTemp loaded_data_hi64 = newTemp(Ity_I64); -+ assign(loaded_data_lo64, unop(Iop_128to64, -+ mkexpr(loaded_data128))); -+ assign(loaded_data_hi64, unop(Iop_128HIto64, -+ mkexpr(loaded_data128))); -+ stmt( IRStmt_Put( OFFB_LLSC_DATA_LO64, -+ mkexpr(loaded_data_lo64) )); -+ stmt( IRStmt_Put( OFFB_LLSC_DATA_HI64, -+ mkexpr(loaded_data_hi64) )); -+ stmt( IRStmt_Put( OFFB_LLSC_ADDR, mkexpr(ea) )); -+ stmt( IRStmt_Put( OFFB_LLSC_SIZE, mkU64(16) )); -+ putIReg64orZR(tt1, mkexpr(loaded_data_lo64)); -+ putIReg64orZR(tt2, mkexpr(loaded_data_hi64)); -+ } -+ } else { -+ // Non-fallback implementation of LL. -+ IRTemp res = newTemp(fullTy); // I64 or I128 -+ stmt(IRStmt_LLSC(Iend_LE, res, mkexpr(ea), NULL/*LL*/)); -+ // Assuming a little-endian guest here. Rt1 goes at the lower -+ // address, so it must live in the least significant half of `res`. -+ IROp opGetLO = fullTy == Ity_I128 ? Iop_128to64 : Iop_64to32; -+ IROp opGetHI = fullTy == Ity_I128 ? Iop_128HIto64 : Iop_64HIto32; -+ putIReg64orZR(tt1, widenUto64(elemTy, unop(opGetLO, mkexpr(res)))); -+ putIReg64orZR(tt2, widenUto64(elemTy, unop(opGetHI, mkexpr(res)))); -+ } -+ if (isAcqOrRel) { -+ stmt(IRStmt_MBE(Imbe_Fence)); -+ } -+ DIP("ld%sxp %s, %s, [%s] %s\n", -+ isAcqOrRel ? (isLD ? "a" : "l") : "", -+ nameIRegOrZR(elemSzB == 8, tt1), -+ nameIRegOrZR(elemSzB == 8, tt2), -+ nameIReg64orSP(nn), -+ abiinfo->guest__use_fallback_LLSC -+ ? "(fallback implementation)" : ""); -+ return True; -+ } -+ if (!isLD) { -+ if (isAcqOrRel) { -+ stmt(IRStmt_MBE(Imbe_Fence)); -+ } -+ if (abiinfo->guest__use_fallback_LLSC) { -+ // Fallback implementation of SC. -+ // This is really ugly, since we don't have any way to do -+ // proper if-then-else. First, set up as if the SC failed, -+ // and jump forwards if it really has failed. -+ -+ // Continuation address -+ IRConst* nia = IRConst_U64(guest_PC_curr_instr + 4); -+ -+ // "the SC failed". Any non-zero value means failure. -+ putIReg64orZR(ss, mkU64(1)); -+ -+ IRTemp tmp_LLsize = newTemp(Ity_I64); -+ assign(tmp_LLsize, IRExpr_Get(OFFB_LLSC_SIZE, Ity_I64)); -+ stmt( IRStmt_Put( OFFB_LLSC_SIZE, mkU64(0) // "no transaction" -+ )); -+ // Fail if no or wrong-size transaction -+ vassert((fullSzB == 8 && fullTy == Ity_I64) -+ || (fullSzB == 16 && fullTy == Ity_I128)); -+ stmt( IRStmt_Exit( -+ binop(Iop_CmpNE64, mkexpr(tmp_LLsize), mkU64(fullSzB)), -+ Ijk_Boring, nia, OFFB_PC -+ )); -+ // Fail if the address doesn't match the LL address -+ stmt( IRStmt_Exit( -+ binop(Iop_CmpNE64, mkexpr(ea), -+ IRExpr_Get(OFFB_LLSC_ADDR, Ity_I64)), -+ Ijk_Boring, nia, OFFB_PC -+ )); -+ // The data to be stored. -+ IRTemp store_data = newTemp(fullTy); -+ if (fullTy == Ity_I64) { -+ assign(store_data, -+ binop(Iop_32HLto64, -+ narrowFrom64(Ity_I32, getIReg64orZR(tt2)), -+ narrowFrom64(Ity_I32, getIReg64orZR(tt1)))); -+ } else { -+ assign(store_data, -+ binop(Iop_64HLto128, -+ getIReg64orZR(tt2), getIReg64orZR(tt1))); -+ } -+ -+ if (fullTy == Ity_I64) { -+ // 64 bit (2x32 bit) path -+ // Fail if the data in memory doesn't match the data stashed by -+ // the LL. -+ IRTemp llsc_data_lo64 = newTemp(Ity_I64); -+ assign(llsc_data_lo64, -+ IRExpr_Get(OFFB_LLSC_DATA_LO64, Ity_I64)); -+ stmt( IRStmt_Exit( -+ binop(Iop_CmpNE64, loadLE(Ity_I64, mkexpr(ea)), -+ mkexpr(llsc_data_lo64)), -+ Ijk_Boring, nia, OFFB_PC -+ )); -+ // Try to CAS the new value in. -+ IRTemp old = newTemp(Ity_I64); -+ IRTemp expd = newTemp(Ity_I64); -+ assign(expd, mkexpr(llsc_data_lo64)); -+ stmt( IRStmt_CAS(mkIRCAS(/*oldHi*/IRTemp_INVALID, old, -+ Iend_LE, mkexpr(ea), -+ /*expdHi*/NULL, mkexpr(expd), -+ /*dataHi*/NULL, mkexpr(store_data) -+ ))); -+ // Fail if the CAS failed (viz, old != expd) -+ stmt( IRStmt_Exit( -+ binop(Iop_CmpNE64, mkexpr(old), mkexpr(expd)), -+ Ijk_Boring, nia, OFFB_PC -+ )); -+ } else { -+ // 128 bit (2x64 bit) path -+ // Fail if the data in memory doesn't match the data stashed by -+ // the LL. -+ IRTemp llsc_data_lo64 = newTemp(Ity_I64); -+ assign(llsc_data_lo64, -+ IRExpr_Get(OFFB_LLSC_DATA_LO64, Ity_I64)); -+ IRTemp llsc_data_hi64 = newTemp(Ity_I64); -+ assign(llsc_data_hi64, -+ IRExpr_Get(OFFB_LLSC_DATA_HI64, Ity_I64)); -+ IRTemp data_at_ea = newTemp(Ity_I128); -+ assign(data_at_ea, -+ unop(Iop_ReinterpV128asI128, -+ loadLE(Ity_V128, mkexpr(ea)))); -+ stmt( IRStmt_Exit( -+ binop(Iop_CmpNE64, -+ unop(Iop_128to64, mkexpr(data_at_ea)), -+ mkexpr(llsc_data_lo64)), -+ Ijk_Boring, nia, OFFB_PC -+ )); -+ stmt( IRStmt_Exit( -+ binop(Iop_CmpNE64, -+ unop(Iop_128HIto64, mkexpr(data_at_ea)), -+ mkexpr(llsc_data_hi64)), -+ Ijk_Boring, nia, OFFB_PC -+ )); -+ // Try to CAS the new value in. -+ IRTemp old_lo64 = newTemp(Ity_I64); -+ IRTemp old_hi64 = newTemp(Ity_I64); -+ IRTemp expd_lo64 = newTemp(Ity_I64); -+ IRTemp expd_hi64 = newTemp(Ity_I64); -+ IRTemp store_data_lo64 = newTemp(Ity_I64); -+ IRTemp store_data_hi64 = newTemp(Ity_I64); -+ assign(expd_lo64, mkexpr(llsc_data_lo64)); -+ assign(expd_hi64, mkexpr(llsc_data_hi64)); -+ assign(store_data_lo64, unop(Iop_128to64, mkexpr(store_data))); -+ assign(store_data_hi64, unop(Iop_128HIto64, mkexpr(store_data))); -+ stmt( IRStmt_CAS(mkIRCAS(old_hi64, old_lo64, -+ Iend_LE, mkexpr(ea), -+ mkexpr(expd_hi64), mkexpr(expd_lo64), -+ mkexpr(store_data_hi64), -+ mkexpr(store_data_lo64) -+ ))); -+ // Fail if the CAS failed (viz, old != expd) -+ stmt( IRStmt_Exit( -+ binop(Iop_CmpNE64, mkexpr(old_lo64), mkexpr(expd_lo64)), -+ Ijk_Boring, nia, OFFB_PC -+ )); -+ stmt( IRStmt_Exit( -+ binop(Iop_CmpNE64, mkexpr(old_hi64), mkexpr(expd_hi64)), -+ Ijk_Boring, nia, OFFB_PC -+ )); -+ } -+ // Otherwise we succeeded (!) -+ putIReg64orZR(ss, mkU64(0)); -+ } else { -+ // Non-fallback implementation of SC. -+ IRTemp res = newTemp(Ity_I1); -+ IRExpr* dataLO = narrowFrom64(elemTy, getIReg64orZR(tt1)); -+ IRExpr* dataHI = narrowFrom64(elemTy, getIReg64orZR(tt2)); -+ IROp opMerge = fullTy == Ity_I128 ? Iop_64HLto128 : Iop_32HLto64; -+ IRExpr* data = binop(opMerge, dataHI, dataLO); -+ // Assuming a little-endian guest here. Rt1 goes at the lower -+ // address, so it must live in the least significant half of `data`. -+ stmt(IRStmt_LLSC(Iend_LE, res, mkexpr(ea), data)); -+ /* IR semantics: res is 1 if store succeeds, 0 if it fails. -+ Need to set rS to 1 on failure, 0 on success. */ -+ putIReg64orZR(ss, binop(Iop_Xor64, unop(Iop_1Uto64, mkexpr(res)), -+ mkU64(1))); -+ } -+ DIP("st%sxp %s, %s, %s, [%s] %s\n", -+ isAcqOrRel ? (isLD ? "a" : "l") : "", -+ nameIRegOrZR(False, ss), -+ nameIRegOrZR(elemSzB == 8, tt1), -+ nameIRegOrZR(elemSzB == 8, tt2), -+ nameIReg64orSP(nn), -+ abiinfo->guest__use_fallback_LLSC -+ ? "(fallback implementation)" : ""); -+ return True; -+ } -+ /* else fall through */ -+ } -+ - /* ------------------ LDA{R,RH,RB} ------------------ */ - /* ------------------ STL{R,RH,RB} ------------------ */ - /* 31 29 23 20 14 9 4 -diff --git a/VEX/priv/host_arm64_defs.c b/VEX/priv/host_arm64_defs.c -index 5657bcab9..b65e27db4 100644 ---- a/VEX/priv/host_arm64_defs.c -+++ b/VEX/priv/host_arm64_defs.c -@@ -1059,6 +1059,16 @@ ARM64Instr* ARM64Instr_StrEX ( Int szB ) { - vassert(szB == 8 || szB == 4 || szB == 2 || szB == 1); - return i; - } -+ARM64Instr* ARM64Instr_LdrEXP ( void ) { -+ ARM64Instr* i = LibVEX_Alloc_inline(sizeof(ARM64Instr)); -+ i->tag = ARM64in_LdrEXP; -+ return i; -+} -+ARM64Instr* ARM64Instr_StrEXP ( void ) { -+ ARM64Instr* i = LibVEX_Alloc_inline(sizeof(ARM64Instr)); -+ i->tag = ARM64in_StrEXP; -+ return i; -+} - ARM64Instr* ARM64Instr_CAS ( Int szB ) { - ARM64Instr* i = LibVEX_Alloc_inline(sizeof(ARM64Instr)); - i->tag = ARM64in_CAS; -@@ -1699,12 +1709,19 @@ void ppARM64Instr ( const ARM64Instr* i ) { - sz, i->ARM64in.StrEX.szB == 8 ? 'x' : 'w'); - return; - } -+ case ARM64in_LdrEXP: -+ vex_printf("ldxp x2, x3, [x4]"); -+ return; -+ case ARM64in_StrEXP: -+ vex_printf("stxp w0, x2, x3, [x4]"); -+ return; - case ARM64in_CAS: { - vex_printf("x1 = cas(%dbit)(x3, x5 -> x7)", 8 * i->ARM64in.CAS.szB); - return; - } - case ARM64in_CASP: { -- vex_printf("x0,x1 = casp(%dbit)(x2, x4,x5 -> x6,x7)", 8 * i->ARM64in.CASP.szB); -+ vex_printf("x0,x1 = casp(2x%dbit)(x2, x4,x5 -> x6,x7)", -+ 8 * i->ARM64in.CASP.szB); - return; - } - case ARM64in_MFence: -@@ -2253,6 +2270,17 @@ void getRegUsage_ARM64Instr ( HRegUsage* u, const ARM64Instr* i, Bool mode64 ) - addHRegUse(u, HRmWrite, hregARM64_X0()); - addHRegUse(u, HRmRead, hregARM64_X2()); - return; -+ case ARM64in_LdrEXP: -+ addHRegUse(u, HRmRead, hregARM64_X4()); -+ addHRegUse(u, HRmWrite, hregARM64_X2()); -+ addHRegUse(u, HRmWrite, hregARM64_X3()); -+ return; -+ case ARM64in_StrEXP: -+ addHRegUse(u, HRmRead, hregARM64_X4()); -+ addHRegUse(u, HRmWrite, hregARM64_X0()); -+ addHRegUse(u, HRmRead, hregARM64_X2()); -+ addHRegUse(u, HRmRead, hregARM64_X3()); -+ return; - case ARM64in_CAS: - addHRegUse(u, HRmRead, hregARM64_X3()); - addHRegUse(u, HRmRead, hregARM64_X5()); -@@ -2571,6 +2599,10 @@ void mapRegs_ARM64Instr ( HRegRemap* m, ARM64Instr* i, Bool mode64 ) - return; - case ARM64in_StrEX: - return; -+ case ARM64in_LdrEXP: -+ return; -+ case ARM64in_StrEXP: -+ return; - case ARM64in_CAS: - return; - case ARM64in_CASP: -@@ -4167,6 +4199,16 @@ Int emit_ARM64Instr ( /*MB_MOD*/Bool* is_profInc, - } - goto bad; - } -+ case ARM64in_LdrEXP: { -+ // 820C7FC8 ldxp x2, x3, [x4] -+ *p++ = 0xC87F0C82; -+ goto done; -+ } -+ case ARM64in_StrEXP: { -+ // 820C20C8 stxp w0, x2, x3, [x4] -+ *p++ = 0xC8200C82; -+ goto done; -+ } - case ARM64in_CAS: { - /* This isn't simple. For an explanation see the comment in - host_arm64_defs.h on the definition of ARM64Instr case CAS. -diff --git a/VEX/priv/host_arm64_defs.h b/VEX/priv/host_arm64_defs.h -index 01fb5708e..dc686dff7 100644 ---- a/VEX/priv/host_arm64_defs.h -+++ b/VEX/priv/host_arm64_defs.h -@@ -509,8 +509,10 @@ typedef - ARM64in_AddToSP, /* move SP by small, signed constant */ - ARM64in_FromSP, /* move SP to integer register */ - ARM64in_Mul, -- ARM64in_LdrEX, -- ARM64in_StrEX, -+ ARM64in_LdrEX, /* load exclusive, single register */ -+ ARM64in_StrEX, /* store exclusive, single register */ -+ ARM64in_LdrEXP, /* load exclusive, register pair, 2x64-bit only */ -+ ARM64in_StrEXP, /* store exclusive, register pair, 2x64-bit only */ - ARM64in_CAS, - ARM64in_CASP, - ARM64in_MFence, -@@ -719,6 +721,12 @@ typedef - struct { - Int szB; /* 1, 2, 4 or 8 */ - } StrEX; -+ /* LDXP x2, x3, [x4]. This is 2x64-bit only. */ -+ struct { -+ } LdrEXP; -+ /* STXP w0, x2, x3, [x4]. This is 2x64-bit only. */ -+ struct { -+ } StrEXP; - /* x1 = CAS(x3(addr), x5(expected) -> x7(new)), - and trashes x8 - where x1[8*szB-1 : 0] == x5[8*szB-1 : 0] indicates success, -@@ -1037,6 +1045,8 @@ extern ARM64Instr* ARM64Instr_Mul ( HReg dst, HReg argL, HReg argR, - ARM64MulOp op ); - extern ARM64Instr* ARM64Instr_LdrEX ( Int szB ); - extern ARM64Instr* ARM64Instr_StrEX ( Int szB ); -+extern ARM64Instr* ARM64Instr_LdrEXP ( void ); -+extern ARM64Instr* ARM64Instr_StrEXP ( void ); - extern ARM64Instr* ARM64Instr_CAS ( Int szB ); - extern ARM64Instr* ARM64Instr_CASP ( Int szB ); - extern ARM64Instr* ARM64Instr_MFence ( void ); -diff --git a/VEX/priv/host_arm64_isel.c b/VEX/priv/host_arm64_isel.c -index 4b1d8c846..094e7e74b 100644 ---- a/VEX/priv/host_arm64_isel.c -+++ b/VEX/priv/host_arm64_isel.c -@@ -196,9 +196,9 @@ static HReg iselCondCode_R ( ISelEnv* env, IRExpr* e ); - static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ); - static HReg iselIntExpr_R ( ISelEnv* env, IRExpr* e ); - --static void iselInt128Expr_wrk ( /*OUT*/HReg* rHi, HReg* rLo, -+static void iselInt128Expr_wrk ( /*OUT*/HReg* rHi, /*OUT*/HReg* rLo, - ISelEnv* env, IRExpr* e ); --static void iselInt128Expr ( /*OUT*/HReg* rHi, HReg* rLo, -+static void iselInt128Expr ( /*OUT*/HReg* rHi, /*OUT*/HReg* rLo, - ISelEnv* env, IRExpr* e ); - - static HReg iselDblExpr_wrk ( ISelEnv* env, IRExpr* e ); -@@ -1759,9 +1759,12 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) - - /* AND/OR/XOR(e1, e2) (for any e1, e2) */ - switch (e->Iex.Binop.op) { -- case Iop_And64: case Iop_And32: lop = ARM64lo_AND; goto log_binop; -- case Iop_Or64: case Iop_Or32: case Iop_Or16: lop = ARM64lo_OR; goto log_binop; -- case Iop_Xor64: case Iop_Xor32: lop = ARM64lo_XOR; goto log_binop; -+ case Iop_And64: case Iop_And32: -+ lop = ARM64lo_AND; goto log_binop; -+ case Iop_Or64: case Iop_Or32: case Iop_Or16: -+ lop = ARM64lo_OR; goto log_binop; -+ case Iop_Xor64: case Iop_Xor32: -+ lop = ARM64lo_XOR; goto log_binop; - log_binop: { - HReg dst = newVRegI(env); - HReg argL = iselIntExpr_R(env, e->Iex.Binop.arg1); -@@ -2013,6 +2016,11 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) - iselInt128Expr(&rHi,&rLo, env, e->Iex.Unop.arg); - return rHi; /* and abandon rLo */ - } -+ case Iop_128to64: { -+ HReg rHi, rLo; -+ iselInt128Expr(&rHi,&rLo, env, e->Iex.Unop.arg); -+ return rLo; /* and abandon rHi */ -+ } - case Iop_8Sto32: case Iop_8Sto64: { - IRExpr* arg = e->Iex.Unop.arg; - HReg src = iselIntExpr_R(env, arg); -@@ -2185,13 +2193,19 @@ static HReg iselIntExpr_R_wrk ( ISelEnv* env, IRExpr* e ) - } - return dst; - } -+ case Iop_64HIto32: { -+ HReg dst = newVRegI(env); -+ HReg src = iselIntExpr_R(env, e->Iex.Unop.arg); -+ addInstr(env, ARM64Instr_Shift(dst, src, ARM64RI6_I6(32), -+ ARM64sh_SHR)); -+ return dst; -+ } - case Iop_64to32: - case Iop_64to16: - case Iop_64to8: - case Iop_32to16: - /* These are no-ops. */ - return iselIntExpr_R(env, e->Iex.Unop.arg); -- - default: - break; - } -@@ -2335,6 +2349,43 @@ static void iselInt128Expr_wrk ( HReg* rHi, HReg* rLo, - vassert(e); - vassert(typeOfIRExpr(env->type_env,e) == Ity_I128); - -+ /* --------- TEMP --------- */ -+ if (e->tag == Iex_RdTmp) { -+ lookupIRTempPair(rHi, rLo, env, e->Iex.RdTmp.tmp); -+ return; -+ } -+ -+ /* --------- CONST --------- */ -+ if (e->tag == Iex_Const) { -+ IRConst* c = e->Iex.Const.con; -+ vassert(c->tag == Ico_U128); -+ if (c->Ico.U128 == 0) { -+ // The only case we need to handle (so far) -+ HReg zero = newVRegI(env); -+ addInstr(env, ARM64Instr_Imm64(zero, 0)); -+ *rHi = *rLo = zero; -+ return; -+ } -+ } -+ -+ /* --------- UNARY ops --------- */ -+ if (e->tag == Iex_Unop) { -+ switch (e->Iex.Unop.op) { -+ case Iop_ReinterpV128asI128: { -+ HReg dstHi = newVRegI(env); -+ HReg dstLo = newVRegI(env); -+ HReg src = iselV128Expr(env, e->Iex.Unop.arg); -+ addInstr(env, ARM64Instr_VXfromQ(dstHi, src, 1)); -+ addInstr(env, ARM64Instr_VXfromQ(dstLo, src, 0)); -+ *rHi = dstHi; -+ *rLo = dstLo; -+ return; -+ } -+ default: -+ break; -+ } -+ } -+ - /* --------- BINARY ops --------- */ - if (e->tag == Iex_Binop) { - switch (e->Iex.Binop.op) { -@@ -4086,6 +4137,14 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) - addInstr(env, ARM64Instr_VMov(8/*yes, really*/, dst, src)); - return; - } -+ if (ty == Ity_I128) { -+ HReg rHi, rLo, dstHi, dstLo; -+ iselInt128Expr(&rHi,&rLo, env, stmt->Ist.WrTmp.data); -+ lookupIRTempPair( &dstHi, &dstLo, env, tmp); -+ addInstr(env, ARM64Instr_MovI(dstHi, rHi)); -+ addInstr(env, ARM64Instr_MovI(dstLo, rLo)); -+ return; -+ } - if (ty == Ity_V128) { - HReg src = iselV128Expr(env, stmt->Ist.WrTmp.data); - HReg dst = lookupIRTemp(env, tmp); -@@ -4183,42 +4242,67 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) - /* LL */ - IRTemp res = stmt->Ist.LLSC.result; - IRType ty = typeOfIRTemp(env->type_env, res); -- if (ty == Ity_I64 || ty == Ity_I32 -+ if (ty == Ity_I128 || ty == Ity_I64 || ty == Ity_I32 - || ty == Ity_I16 || ty == Ity_I8) { - Int szB = 0; -- HReg r_dst = lookupIRTemp(env, res); - HReg raddr = iselIntExpr_R(env, stmt->Ist.LLSC.addr); - switch (ty) { -- case Ity_I8: szB = 1; break; -- case Ity_I16: szB = 2; break; -- case Ity_I32: szB = 4; break; -- case Ity_I64: szB = 8; break; -- default: vassert(0); -+ case Ity_I8: szB = 1; break; -+ case Ity_I16: szB = 2; break; -+ case Ity_I32: szB = 4; break; -+ case Ity_I64: szB = 8; break; -+ case Ity_I128: szB = 16; break; -+ default: vassert(0); -+ } -+ if (szB == 16) { -+ HReg r_dstMSword = INVALID_HREG; -+ HReg r_dstLSword = INVALID_HREG; -+ lookupIRTempPair(&r_dstMSword, &r_dstLSword, env, res); -+ addInstr(env, ARM64Instr_MovI(hregARM64_X4(), raddr)); -+ addInstr(env, ARM64Instr_LdrEXP()); -+ addInstr(env, ARM64Instr_MovI(r_dstLSword, hregARM64_X2())); -+ addInstr(env, ARM64Instr_MovI(r_dstMSword, hregARM64_X3())); -+ } else { -+ vassert(szB != 0); -+ HReg r_dst = lookupIRTemp(env, res); -+ addInstr(env, ARM64Instr_MovI(hregARM64_X4(), raddr)); -+ addInstr(env, ARM64Instr_LdrEX(szB)); -+ addInstr(env, ARM64Instr_MovI(r_dst, hregARM64_X2())); - } -- addInstr(env, ARM64Instr_MovI(hregARM64_X4(), raddr)); -- addInstr(env, ARM64Instr_LdrEX(szB)); -- addInstr(env, ARM64Instr_MovI(r_dst, hregARM64_X2())); - return; - } - goto stmt_fail; - } else { - /* SC */ - IRType tyd = typeOfIRExpr(env->type_env, stmt->Ist.LLSC.storedata); -- if (tyd == Ity_I64 || tyd == Ity_I32 -+ if (tyd == Ity_I128 || tyd == Ity_I64 || tyd == Ity_I32 - || tyd == Ity_I16 || tyd == Ity_I8) { - Int szB = 0; -- HReg rD = iselIntExpr_R(env, stmt->Ist.LLSC.storedata); - HReg rA = iselIntExpr_R(env, stmt->Ist.LLSC.addr); - switch (tyd) { -- case Ity_I8: szB = 1; break; -- case Ity_I16: szB = 2; break; -- case Ity_I32: szB = 4; break; -- case Ity_I64: szB = 8; break; -- default: vassert(0); -+ case Ity_I8: szB = 1; break; -+ case Ity_I16: szB = 2; break; -+ case Ity_I32: szB = 4; break; -+ case Ity_I64: szB = 8; break; -+ case Ity_I128: szB = 16; break; -+ default: vassert(0); -+ } -+ if (szB == 16) { -+ HReg rD_MSword = INVALID_HREG; -+ HReg rD_LSword = INVALID_HREG; -+ iselInt128Expr(&rD_MSword, -+ &rD_LSword, env, stmt->Ist.LLSC.storedata); -+ addInstr(env, ARM64Instr_MovI(hregARM64_X2(), rD_LSword)); -+ addInstr(env, ARM64Instr_MovI(hregARM64_X3(), rD_MSword)); -+ addInstr(env, ARM64Instr_MovI(hregARM64_X4(), rA)); -+ addInstr(env, ARM64Instr_StrEXP()); -+ } else { -+ vassert(szB != 0); -+ HReg rD = iselIntExpr_R(env, stmt->Ist.LLSC.storedata); -+ addInstr(env, ARM64Instr_MovI(hregARM64_X2(), rD)); -+ addInstr(env, ARM64Instr_MovI(hregARM64_X4(), rA)); -+ addInstr(env, ARM64Instr_StrEX(szB)); - } -- addInstr(env, ARM64Instr_MovI(hregARM64_X2(), rD)); -- addInstr(env, ARM64Instr_MovI(hregARM64_X4(), rA)); -- addInstr(env, ARM64Instr_StrEX(szB)); - } else { - goto stmt_fail; - } -@@ -4243,10 +4327,10 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) - - /* --------- ACAS --------- */ - case Ist_CAS: { -- if (stmt->Ist.CAS.details->oldHi == IRTemp_INVALID) { -+ IRCAS* cas = stmt->Ist.CAS.details; -+ if (cas->oldHi == IRTemp_INVALID && cas->end == Iend_LE) { - /* "normal" singleton CAS */ - UChar sz; -- IRCAS* cas = stmt->Ist.CAS.details; - IRType ty = typeOfIRExpr(env->type_env, cas->dataLo); - switch (ty) { - case Ity_I64: sz = 8; break; -@@ -4281,10 +4365,9 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt ) - addInstr(env, ARM64Instr_MovI(rOld, rResult)); - return; - } -- else { -+ if (cas->oldHi != IRTemp_INVALID && cas->end == Iend_LE) { - /* Paired register CAS, i.e. CASP */ - UChar sz; -- IRCAS* cas = stmt->Ist.CAS.details; - IRType ty = typeOfIRExpr(env->type_env, cas->dataLo); - switch (ty) { - case Ity_I64: sz = 8; break; -diff --git a/VEX/priv/ir_defs.c b/VEX/priv/ir_defs.c -index 25566c41c..2d82c41a1 100644 ---- a/VEX/priv/ir_defs.c -+++ b/VEX/priv/ir_defs.c -@@ -76,6 +76,7 @@ void ppIRConst ( const IRConst* con ) - case Ico_U16: vex_printf( "0x%x:I16", (UInt)(con->Ico.U16)); break; - case Ico_U32: vex_printf( "0x%x:I32", (UInt)(con->Ico.U32)); break; - case Ico_U64: vex_printf( "0x%llx:I64", (ULong)(con->Ico.U64)); break; -+ case Ico_U128: vex_printf( "I128{0x%04x}", (UInt)(con->Ico.U128)); break; - case Ico_F32: u.f32 = con->Ico.F32; - vex_printf( "F32{0x%x}", u.i32); - break; -@@ -2266,6 +2267,13 @@ IRConst* IRConst_U64 ( ULong u64 ) - c->Ico.U64 = u64; - return c; - } -+IRConst* IRConst_U128 ( UShort con ) -+{ -+ IRConst* c = LibVEX_Alloc_inline(sizeof(IRConst)); -+ c->tag = Ico_U128; -+ c->Ico.U128 = con; -+ return c; -+} - IRConst* IRConst_F32 ( Float f32 ) - { - IRConst* c = LibVEX_Alloc_inline(sizeof(IRConst)); -@@ -4230,6 +4238,7 @@ IRType typeOfIRConst ( const IRConst* con ) - case Ico_U16: return Ity_I16; - case Ico_U32: return Ity_I32; - case Ico_U64: return Ity_I64; -+ case Ico_U128: return Ity_I128; - case Ico_F32: return Ity_F32; - case Ico_F32i: return Ity_F32; - case Ico_F64: return Ity_F64; -@@ -5129,7 +5138,7 @@ void tcStmt ( const IRSB* bb, const IRStmt* stmt, IRType gWordTy ) - tyRes = typeOfIRTemp(tyenv, stmt->Ist.LLSC.result); - if (stmt->Ist.LLSC.storedata == NULL) { - /* it's a LL */ -- if (tyRes != Ity_I64 && tyRes != Ity_I32 -+ if (tyRes != Ity_I128 && tyRes != Ity_I64 && tyRes != Ity_I32 - && tyRes != Ity_I16 && tyRes != Ity_I8) - sanityCheckFail(bb,stmt,"Ist.LLSC(LL).result :: bogus"); - } else { -@@ -5137,7 +5146,7 @@ void tcStmt ( const IRSB* bb, const IRStmt* stmt, IRType gWordTy ) - if (tyRes != Ity_I1) - sanityCheckFail(bb,stmt,"Ist.LLSC(SC).result: not :: Ity_I1"); - tyData = typeOfIRExpr(tyenv, stmt->Ist.LLSC.storedata); -- if (tyData != Ity_I64 && tyData != Ity_I32 -+ if (tyData != Ity_I128 && tyData != Ity_I64 && tyData != Ity_I32 - && tyData != Ity_I16 && tyData != Ity_I8) - sanityCheckFail(bb,stmt, - "Ist.LLSC(SC).result :: storedata bogus"); -@@ -5385,6 +5394,7 @@ Int sizeofIRType ( IRType ty ) - IRType integerIRTypeOfSize ( Int szB ) - { - switch (szB) { -+ case 16: return Ity_I128; - case 8: return Ity_I64; - case 4: return Ity_I32; - case 2: return Ity_I16; -diff --git a/VEX/pub/libvex_guest_arm64.h b/VEX/pub/libvex_guest_arm64.h -index 39b6ecdc2..91d06bd75 100644 ---- a/VEX/pub/libvex_guest_arm64.h -+++ b/VEX/pub/libvex_guest_arm64.h -@@ -157,14 +157,18 @@ typedef - note of bits 23 and 22. */ - UInt guest_FPCR; - -- /* Fallback LL/SC support. See bugs 344524 and 369459. */ -- ULong guest_LLSC_SIZE; // 0==no current transaction, else 1,2,4 or 8. -+ /* Fallback LL/SC support. See bugs 344524 and 369459. _LO64 and _HI64 -+ contain the original contents of _ADDR+0 .. _ADDR+15, but only _SIZE -+ number of bytes of it. The remaining 16-_SIZE bytes of them must be -+ zero. */ -+ ULong guest_LLSC_SIZE; // 0==no current transaction, else 1,2,4,8 or 16. - ULong guest_LLSC_ADDR; // Address of transaction. -- ULong guest_LLSC_DATA; // Original value at _ADDR, zero-extended. -+ ULong guest_LLSC_DATA_LO64; // Original value at _ADDR+0. -+ ULong guest_LLSC_DATA_HI64; // Original value at _ADDR+8. - - /* Padding to make it have an 16-aligned size */ - /* UInt pad_end_0; */ -- ULong pad_end_1; -+ /* ULong pad_end_1; */ - } - VexGuestARM64State; - -diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h -index deaa044c1..85805bb69 100644 ---- a/VEX/pub/libvex_ir.h -+++ b/VEX/pub/libvex_ir.h -@@ -269,6 +269,8 @@ typedef - Ico_U16, - Ico_U32, - Ico_U64, -+ Ico_U128, /* 128-bit restricted integer constant, -+ same encoding scheme as V128 */ - Ico_F32, /* 32-bit IEEE754 floating */ - Ico_F32i, /* 32-bit unsigned int to be interpreted literally - as a IEEE754 single value. */ -@@ -295,6 +297,7 @@ typedef - UShort U16; - UInt U32; - ULong U64; -+ UShort U128; - Float F32; - UInt F32i; - Double F64; -@@ -311,6 +314,7 @@ extern IRConst* IRConst_U8 ( UChar ); - extern IRConst* IRConst_U16 ( UShort ); - extern IRConst* IRConst_U32 ( UInt ); - extern IRConst* IRConst_U64 ( ULong ); -+extern IRConst* IRConst_U128 ( UShort ); - extern IRConst* IRConst_F32 ( Float ); - extern IRConst* IRConst_F32i ( UInt ); - extern IRConst* IRConst_F64 ( Double ); -diff --git a/memcheck/mc_machine.c b/memcheck/mc_machine.c -index 919c7fae8..176c8e5cb 100644 ---- a/memcheck/mc_machine.c -+++ b/memcheck/mc_machine.c -@@ -1115,9 +1115,10 @@ static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ) - if (o == GOF(CMSTART) && sz == 8) return -1; // untracked - if (o == GOF(CMLEN) && sz == 8) return -1; // untracked - -- if (o == GOF(LLSC_SIZE) && sz == 8) return -1; // untracked -- if (o == GOF(LLSC_ADDR) && sz == 8) return o; -- if (o == GOF(LLSC_DATA) && sz == 8) return o; -+ if (o == GOF(LLSC_SIZE) && sz == 8) return -1; // untracked -+ if (o == GOF(LLSC_ADDR) && sz == 8) return o; -+ if (o == GOF(LLSC_DATA_LO64) && sz == 8) return o; -+ if (o == GOF(LLSC_DATA_HI64) && sz == 8) return o; - - VG_(printf)("MC_(get_otrack_shadow_offset)(arm64)(off=%d,sz=%d)\n", - offset,szB); -diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c -index c6fd2653f..72ccb3c8c 100644 ---- a/memcheck/mc_translate.c -+++ b/memcheck/mc_translate.c -@@ -5497,8 +5497,11 @@ IRAtom* expr2vbits_Load_WRK ( MCEnv* mce, - the address (shadow) to 'defined' following the test. */ - complainIfUndefined( mce, addr, guard ); - -- /* Now cook up a call to the relevant helper function, to read the -- data V bits from shadow memory. */ -+ /* Now cook up a call to the relevant helper function, to read the data V -+ bits from shadow memory. Note that I128 loads are done by pretending -+ we're doing a V128 load, and then converting the resulting V128 vbits -+ word to an I128, right at the end of this function -- see `castedToI128` -+ below. (It's only a minor hack :-) This pertains to bug 444399. */ - ty = shadowTypeV(ty); - - void* helper = NULL; -@@ -5511,6 +5514,7 @@ IRAtom* expr2vbits_Load_WRK ( MCEnv* mce, - hname = "MC_(helperc_LOADV256le)"; - ret_via_outparam = True; - break; -+ case Ity_I128: // fallthrough. See comment above. - case Ity_V128: helper = &MC_(helperc_LOADV128le); - hname = "MC_(helperc_LOADV128le)"; - ret_via_outparam = True; -@@ -5576,7 +5580,7 @@ IRAtom* expr2vbits_Load_WRK ( MCEnv* mce, - - /* We need to have a place to park the V bits we're just about to - read. */ -- IRTemp datavbits = newTemp(mce, ty, VSh); -+ IRTemp datavbits = newTemp(mce, ty == Ity_I128 ? Ity_V128 : ty, VSh); - - /* Here's the call. */ - IRDirty* di; -@@ -5603,7 +5607,14 @@ IRAtom* expr2vbits_Load_WRK ( MCEnv* mce, - } - stmt( 'V', mce, IRStmt_Dirty(di) ); - -- return mkexpr(datavbits); -+ if (ty == Ity_I128) { -+ IRAtom* castedToI128 -+ = assignNew('V', mce, Ity_I128, -+ unop(Iop_ReinterpV128asI128, mkexpr(datavbits))); -+ return castedToI128; -+ } else { -+ return mkexpr(datavbits); -+ } - } - - -@@ -5631,6 +5642,7 @@ IRAtom* expr2vbits_Load ( MCEnv* mce, - case Ity_I16: - case Ity_I32: - case Ity_I64: -+ case Ity_I128: - case Ity_V128: - case Ity_V256: - return expr2vbits_Load_WRK(mce, end, ty, addr, bias, guard); -@@ -5928,6 +5940,7 @@ void do_shadow_Store ( MCEnv* mce, - c = IRConst_V256(V_BITS32_DEFINED); break; - case Ity_V128: // V128 weirdness -- used twice - c = IRConst_V128(V_BITS16_DEFINED); break; -+ case Ity_I128: c = IRConst_U128(V_BITS16_DEFINED); break; - case Ity_I64: c = IRConst_U64 (V_BITS64_DEFINED); break; - case Ity_I32: c = IRConst_U32 (V_BITS32_DEFINED); break; - case Ity_I16: c = IRConst_U16 (V_BITS16_DEFINED); break; -@@ -5948,6 +5961,7 @@ void do_shadow_Store ( MCEnv* mce, - switch (ty) { - case Ity_V256: /* we'll use the helper four times */ - case Ity_V128: /* we'll use the helper twice */ -+ case Ity_I128: /* we'll use the helper twice */ - case Ity_I64: helper = &MC_(helperc_STOREV64le); - hname = "MC_(helperc_STOREV64le)"; - break; -@@ -6051,9 +6065,9 @@ void do_shadow_Store ( MCEnv* mce, - stmt( 'V', mce, IRStmt_Dirty(diQ3) ); - - } -- else if (UNLIKELY(ty == Ity_V128)) { -+ else if (UNLIKELY(ty == Ity_V128 || ty == Ity_I128)) { - -- /* V128-bit case */ -+ /* V128/I128-bit case */ - /* See comment in next clause re 64-bit regparms */ - /* also, need to be careful about endianness */ - -@@ -6062,6 +6076,7 @@ void do_shadow_Store ( MCEnv* mce, - IRAtom *addrLo64, *addrHi64; - IRAtom *vdataLo64, *vdataHi64; - IRAtom *eBiasLo64, *eBiasHi64; -+ IROp opGetLO64, opGetHI64; - - if (end == Iend_LE) { - offLo64 = 0; -@@ -6071,9 +6086,17 @@ void do_shadow_Store ( MCEnv* mce, - offHi64 = 0; - } - -+ if (ty == Ity_V128) { -+ opGetLO64 = Iop_V128to64; -+ opGetHI64 = Iop_V128HIto64; -+ } else { -+ opGetLO64 = Iop_128to64; -+ opGetHI64 = Iop_128HIto64; -+ } -+ - eBiasLo64 = tyAddr==Ity_I32 ? mkU32(bias+offLo64) : mkU64(bias+offLo64); - addrLo64 = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBiasLo64) ); -- vdataLo64 = assignNew('V', mce, Ity_I64, unop(Iop_V128to64, vdata)); -+ vdataLo64 = assignNew('V', mce, Ity_I64, unop(opGetLO64, vdata)); - diLo64 = unsafeIRDirty_0_N( - 1/*regparms*/, - hname, VG_(fnptr_to_fnentry)( helper ), -@@ -6081,7 +6104,7 @@ void do_shadow_Store ( MCEnv* mce, - ); - eBiasHi64 = tyAddr==Ity_I32 ? mkU32(bias+offHi64) : mkU64(bias+offHi64); - addrHi64 = assignNew('V', mce, tyAddr, binop(mkAdd, addr, eBiasHi64) ); -- vdataHi64 = assignNew('V', mce, Ity_I64, unop(Iop_V128HIto64, vdata)); -+ vdataHi64 = assignNew('V', mce, Ity_I64, unop(opGetHI64, vdata)); - diHi64 = unsafeIRDirty_0_N( - 1/*regparms*/, - hname, VG_(fnptr_to_fnentry)( helper ), -@@ -6888,7 +6911,7 @@ static void do_shadow_LLSC ( MCEnv* mce, - /* Just treat this as a normal load, followed by an assignment of - the value to .result. */ - /* Stay sane */ -- tl_assert(resTy == Ity_I64 || resTy == Ity_I32 -+ tl_assert(resTy == Ity_I128 || resTy == Ity_I64 || resTy == Ity_I32 - || resTy == Ity_I16 || resTy == Ity_I8); - assign( 'V', mce, resTmp, - expr2vbits_Load( -@@ -6899,7 +6922,7 @@ static void do_shadow_LLSC ( MCEnv* mce, - /* Stay sane */ - IRType dataTy = typeOfIRExpr(mce->sb->tyenv, - stStoredata); -- tl_assert(dataTy == Ity_I64 || dataTy == Ity_I32 -+ tl_assert(dataTy == Ity_I128 || dataTy == Ity_I64 || dataTy == Ity_I32 - || dataTy == Ity_I16 || dataTy == Ity_I8); - do_shadow_Store( mce, stEnd, - stAddr, 0/* addr bias */, -@@ -7684,7 +7707,7 @@ static void schemeS ( MCEnv* mce, IRStmt* st ) - = typeOfIRTemp(mce->sb->tyenv, st->Ist.LLSC.result); - IRExpr* vanillaLoad - = IRExpr_Load(st->Ist.LLSC.end, resTy, st->Ist.LLSC.addr); -- tl_assert(resTy == Ity_I64 || resTy == Ity_I32 -+ tl_assert(resTy == Ity_I128 || resTy == Ity_I64 || resTy == Ity_I32 - || resTy == Ity_I16 || resTy == Ity_I8); - assign( 'B', mce, findShadowTmpB(mce, st->Ist.LLSC.result), - schemeE(mce, vanillaLoad)); -diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am -index 449710020..2b43ef7d7 100644 ---- a/memcheck/tests/Makefile.am -+++ b/memcheck/tests/Makefile.am -@@ -90,6 +90,7 @@ EXTRA_DIST = \ - addressable.stderr.exp addressable.stdout.exp addressable.vgtest \ - atomic_incs.stderr.exp atomic_incs.vgtest \ - atomic_incs.stdout.exp-32bit atomic_incs.stdout.exp-64bit \ -+ atomic_incs.stdout.exp-64bit-and-128bit \ - badaddrvalue.stderr.exp \ - badaddrvalue.stdout.exp badaddrvalue.vgtest \ - exit_on_first_error.stderr.exp \ -diff --git a/memcheck/tests/atomic_incs.c b/memcheck/tests/atomic_incs.c -index f931750f4..1c738c530 100644 ---- a/memcheck/tests/atomic_incs.c -+++ b/memcheck/tests/atomic_incs.c -@@ -22,6 +22,17 @@ - #define NNN 3456987 - - #define IS_8_ALIGNED(_ptr) (0 == (((unsigned long)(_ptr)) & 7)) -+#define IS_16_ALIGNED(_ptr) (0 == (((unsigned long)(_ptr)) & 15)) -+ -+// U128 from libvex_basictypes.h is a 4-x-UInt array, which is a bit -+// inconvenient, hence: -+typedef -+ struct { -+ // assuming little-endianness -+ unsigned long long int lo64; -+ unsigned long long int hi64; -+ } -+ MyU128; - - - __attribute__((noinline)) void atomic_add_8bit ( char* p, int n ) -@@ -712,6 +723,40 @@ __attribute__((noinline)) void atomic_add_64bit ( long long int* p, int n ) - #endif - } - -+__attribute__((noinline)) void atomic_add_128bit ( MyU128* p, -+ unsigned long long int n ) -+{ -+#if defined(VGA_x86) || defined(VGA_ppc32) || defined(VGA_mips32) \ -+ || defined (VGA_nanomips) || defined(VGA_mips64) \ -+ || defined(VGA_amd64) \ -+ || defined(VGA_ppc64be) || defined(VGA_ppc64le) \ -+ || defined(VGA_arm) \ -+ || defined(VGA_s390x) -+ /* do nothing; is not supported */ -+#elif defined(VGA_arm64) -+ unsigned long long int block[3] -+ = { (unsigned long long int)p, (unsigned long long int)n, -+ 0xFFFFFFFFFFFFFFFFULL}; -+ do { -+ __asm__ __volatile__( -+ "mov x5, %0" "\n\t" // &block[0] -+ "ldr x9, [x5, #0]" "\n\t" // p -+ "ldr x10, [x5, #8]" "\n\t" // n -+ "ldxp x7, x8, [x9]" "\n\t" -+ "adds x7, x7, x10" "\n\t" -+ "adc x8, x8, xzr" "\n\t" -+ "stxp w4, x7, x8, [x9]" "\n\t" -+ "str x4, [x5, #16]" "\n\t" -+ : /*out*/ -+ : /*in*/ "r"(&block[0]) -+ : /*trash*/ "memory", "cc", "x5", "x7", "x8", "x9", "x10", "x4" -+ ); -+ } while (block[2] != 0); -+#else -+# error "Unsupported arch" -+#endif -+} -+ - int main ( int argc, char** argv ) - { - int i, status; -@@ -720,8 +765,12 @@ int main ( int argc, char** argv ) - short* p16; - int* p32; - long long int* p64; -+ MyU128* p128; - pid_t child, p2; - -+ assert(sizeof(MyU128) == 16); -+ assert(sysconf(_SC_PAGESIZE) >= 4096); -+ - printf("parent, pre-fork\n"); - - page = mmap( 0, sysconf(_SC_PAGESIZE), -@@ -736,11 +785,13 @@ int main ( int argc, char** argv ) - p16 = (short*)(page+256); - p32 = (int*)(page+512); - p64 = (long long int*)(page+768); -+ p128 = (MyU128*)(page+1024); - - assert( IS_8_ALIGNED(p8) ); - assert( IS_8_ALIGNED(p16) ); - assert( IS_8_ALIGNED(p32) ); - assert( IS_8_ALIGNED(p64) ); -+ assert( IS_16_ALIGNED(p128) ); - - memset(page, 0, 1024); - -@@ -748,6 +799,7 @@ int main ( int argc, char** argv ) - *p16 = 0; - *p32 = 0; - *p64 = 0; -+ p128->lo64 = p128->hi64 = 0; - - child = fork(); - if (child == -1) { -@@ -763,6 +815,7 @@ int main ( int argc, char** argv ) - atomic_add_16bit(p16, 1); - atomic_add_32bit(p32, 1); - atomic_add_64bit(p64, 98765 ); /* ensure we hit the upper 32 bits */ -+ atomic_add_128bit(p128, 0x1000000013374771ULL); // ditto re upper 64 - } - return 1; - /* NOTREACHED */ -@@ -778,6 +831,7 @@ int main ( int argc, char** argv ) - atomic_add_16bit(p16, 1); - atomic_add_32bit(p32, 1); - atomic_add_64bit(p64, 98765 ); /* ensure we hit the upper 32 bits */ -+ atomic_add_128bit(p128, 0x1000000013374771ULL); // ditto re upper 64 - } - - p2 = waitpid(child, &status, 0); -@@ -788,11 +842,17 @@ int main ( int argc, char** argv ) - - printf("FINAL VALUES: 8 bit %d, 16 bit %d, 32 bit %d, 64 bit %lld\n", - (int)(*(signed char*)p8), (int)(*p16), *p32, *p64 ); -+ printf(" 128 bit 0x%016llx:0x%016llx\n", -+ p128->hi64, p128->lo64); - - if (-74 == (int)(*(signed char*)p8) - && 32694 == (int)(*p16) - && 6913974 == *p32 -- && (0LL == *p64 || 682858642110LL == *p64)) { -+ && (0LL == *p64 || 682858642110LL == *p64) -+ && ((0 == p128->hi64 && 0 == p128->lo64) -+ || (0x00000000000697fb == p128->hi64 -+ && 0x6007eb426316d956ULL == p128->lo64)) -+ ) { - printf("PASS\n"); - } else { - printf("FAIL -- see source code for expected values\n"); -diff --git a/memcheck/tests/atomic_incs.stdout.exp-32bit b/memcheck/tests/atomic_incs.stdout.exp-32bit -index c5b8781e5..55e5044b5 100644 ---- a/memcheck/tests/atomic_incs.stdout.exp-32bit -+++ b/memcheck/tests/atomic_incs.stdout.exp-32bit -@@ -3,5 +3,6 @@ child - parent, pre-fork - parent - FINAL VALUES: 8 bit -74, 16 bit 32694, 32 bit 6913974, 64 bit 0 -+ 128 bit 0x0000000000000000:0x0000000000000000 - PASS - parent exits -diff --git a/memcheck/tests/atomic_incs.stdout.exp-64bit b/memcheck/tests/atomic_incs.stdout.exp-64bit -index 82405c520..ca2f4fc97 100644 ---- a/memcheck/tests/atomic_incs.stdout.exp-64bit -+++ b/memcheck/tests/atomic_incs.stdout.exp-64bit -@@ -3,5 +3,6 @@ child - parent, pre-fork - parent - FINAL VALUES: 8 bit -74, 16 bit 32694, 32 bit 6913974, 64 bit 682858642110 -+ 128 bit 0x0000000000000000:0x0000000000000000 - PASS - parent exits -diff --git a/memcheck/tests/atomic_incs.stdout.exp-64bit-and-128bit b/memcheck/tests/atomic_incs.stdout.exp-64bit-and-128bit -new file mode 100644 -index 000000000..ef6580917 ---- /dev/null -+++ b/memcheck/tests/atomic_incs.stdout.exp-64bit-and-128bit -@@ -0,0 +1,8 @@ -+parent, pre-fork -+child -+parent, pre-fork -+parent -+FINAL VALUES: 8 bit -74, 16 bit 32694, 32 bit 6913974, 64 bit 682858642110 -+ 128 bit 0x00000000000697fb:0x6007eb426316d956 -+PASS -+parent exits -diff --git a/none/tests/arm64/Makefile.am b/none/tests/arm64/Makefile.am -index 00cbfa52c..9efb49b27 100644 ---- a/none/tests/arm64/Makefile.am -+++ b/none/tests/arm64/Makefile.am -@@ -12,7 +12,10 @@ EXTRA_DIST = \ - atomics_v81.stdout.exp atomics_v81.stderr.exp atomics_v81.vgtest \ - simd_v81.stdout.exp simd_v81.stderr.exp simd_v81.vgtest \ - fmadd_sub.stdout.exp fmadd_sub.stderr.exp fmadd_sub.vgtest \ -- fp_and_simd_v82.stdout.exp fp_and_simd_v82.stderr.exp fp_and_simd_v82.vgtest -+ fp_and_simd_v82.stdout.exp fp_and_simd_v82.stderr.exp \ -+ fp_and_simd_v82.vgtest \ -+ ldxp_stxp.stdout.exp ldxp_stxp.stderr.exp \ -+ ldxp_stxp_basisimpl.vgtest ldxp_stxp_fallbackimpl.vgtest - - check_PROGRAMS = \ - allexec \ -@@ -20,7 +23,8 @@ check_PROGRAMS = \ - fp_and_simd \ - integer \ - memory \ -- fmadd_sub -+ fmadd_sub \ -+ ldxp_stxp - - if BUILD_ARMV8_CRC_TESTS - check_PROGRAMS += crc32 -diff --git a/none/tests/arm64/ldxp_stxp.c b/none/tests/arm64/ldxp_stxp.c -new file mode 100644 -index 000000000..b5f6ea121 ---- /dev/null -+++ b/none/tests/arm64/ldxp_stxp.c -@@ -0,0 +1,93 @@ -+ -+/* Note, this is only a basic smoke test of LD{A}XP and ST{L}XP. Their -+ atomicity properties are tested by memcheck/tests/atomic_incs.c. */ -+ -+#include -+#include -+#include -+#include -+ -+typedef unsigned int UInt; -+typedef unsigned long long int ULong; -+ -+ -+void initBlock ( ULong* block ) -+{ -+ block[0] = 0x0001020304050607ULL; -+ block[1] = 0x1011121314151617ULL; -+ block[2] = 0x2021222324252627ULL; -+ block[3] = 0x3031323334353637ULL; -+ block[4] = 0x4041424344454647ULL; -+ block[5] = 0x5051525354555657ULL; -+} -+ -+void printBlock ( const char* who, -+ ULong* block, ULong rt1contents, ULong rt2contents, -+ UInt zeroIfSuccess ) -+{ -+ printf("Block %s (%s)\n", who, zeroIfSuccess == 0 ? "success" : "FAILURE" ); -+ for (int i = 0; i < 6; i++) { -+ printf("0x%016llx\n", block[i]); -+ } -+ printf("0x%016llx rt1contents\n", rt1contents); -+ printf("0x%016llx rt2contents\n", rt2contents); -+ printf("\n"); -+} -+ -+int main ( void ) -+{ -+ ULong* block = memalign(16, 6 * sizeof(ULong)); -+ assert(block); -+ -+ ULong rt1in, rt2in, rt1out, rt2out; -+ UInt scRes; -+ -+ // Do ldxp then stxp with x-registers -+ initBlock(block); -+ rt1in = 0x5555666677778888ULL; -+ rt2in = 0xAAAA9999BBBB0000ULL; -+ rt1out = 0x1111222233334444ULL; -+ rt2out = 0xFFFFEEEEDDDDCCCCULL; -+ scRes = 0x55555555; -+ __asm__ __volatile__( -+ "ldxp %1, %2, [%5]" "\n\t" -+ "stxp %w0, %3, %4, [%5]" "\n\t" -+ : /*OUT*/ -+ "=&r"(scRes), // %0 -+ "=&r"(rt1out), // %1 -+ "=&r"(rt2out) // %2 -+ : /*IN*/ -+ "r"(rt1in), // %3 -+ "r"(rt2in), // %4 -+ "r"(&block[2]) // %5 -+ : /*TRASH*/ -+ "memory","cc" -+ ); -+ printBlock("after ldxp/stxp 2x64-bit", block, rt1out, rt2out, scRes); -+ -+ // Do ldxp then stxp with w-registers -+ initBlock(block); -+ rt1in = 0x5555666677778888ULL; -+ rt2in = 0xAAAA9999BBBB0000ULL; -+ rt1out = 0x1111222233334444ULL; -+ rt2out = 0xFFFFEEEEDDDDCCCCULL; -+ scRes = 0x55555555; -+ __asm__ __volatile__( -+ "ldxp %w1, %w2, [%5]" "\n\t" -+ "stxp %w0, %w3, %w4, [%5]" "\n\t" -+ : /*OUT*/ -+ "=&r"(scRes), // %0 -+ "=&r"(rt1out), // %1 -+ "=&r"(rt2out) // %2 -+ : /*IN*/ -+ "r"(rt1in), // %3 -+ "r"(rt2in), // %4 -+ "r"(&block[2]) // %5 -+ : /*TRASH*/ -+ "memory","cc" -+ ); -+ printBlock("after ldxp/stxp 2x32-bit", block, rt1out, rt2out, scRes); -+ -+ free(block); -+ return 0; -+} -diff --git a/none/tests/arm64/ldxp_stxp_basisimpl.stderr.exp b/none/tests/arm64/ldxp_stxp_basisimpl.stderr.exp -new file mode 100644 -index 000000000..e69de29bb -diff --git a/none/tests/arm64/ldxp_stxp_basisimpl.stdout.exp b/none/tests/arm64/ldxp_stxp_basisimpl.stdout.exp -new file mode 100644 -index 000000000..f269ecdcc ---- /dev/null -+++ b/none/tests/arm64/ldxp_stxp_basisimpl.stdout.exp -@@ -0,0 +1,20 @@ -+Block after ldxp/stxp 2x64-bit (success) -+0x0001020304050607 -+0x1011121314151617 -+0x5555666677778888 -+0xaaaa9999bbbb0000 -+0x4041424344454647 -+0x5051525354555657 -+0x2021222324252627 rt1contents -+0x3031323334353637 rt2contents -+ -+Block after ldxp/stxp 2x32-bit (success) -+0x0001020304050607 -+0x1011121314151617 -+0xbbbb000077778888 -+0x3031323334353637 -+0x4041424344454647 -+0x5051525354555657 -+0x0000000024252627 rt1contents -+0x0000000020212223 rt2contents -+ -diff --git a/none/tests/arm64/ldxp_stxp_basisimpl.vgtest b/none/tests/arm64/ldxp_stxp_basisimpl.vgtest -new file mode 100644 -index 000000000..29133729a ---- /dev/null -+++ b/none/tests/arm64/ldxp_stxp_basisimpl.vgtest -@@ -0,0 +1,2 @@ -+prog: ldxp_stxp -+vgopts: -q -diff --git a/none/tests/arm64/ldxp_stxp_fallbackimpl.stderr.exp b/none/tests/arm64/ldxp_stxp_fallbackimpl.stderr.exp -new file mode 100644 -index 000000000..e69de29bb -diff --git a/none/tests/arm64/ldxp_stxp_fallbackimpl.stdout.exp b/none/tests/arm64/ldxp_stxp_fallbackimpl.stdout.exp -new file mode 100644 -index 000000000..f269ecdcc ---- /dev/null -+++ b/none/tests/arm64/ldxp_stxp_fallbackimpl.stdout.exp -@@ -0,0 +1,20 @@ -+Block after ldxp/stxp 2x64-bit (success) -+0x0001020304050607 -+0x1011121314151617 -+0x5555666677778888 -+0xaaaa9999bbbb0000 -+0x4041424344454647 -+0x5051525354555657 -+0x2021222324252627 rt1contents -+0x3031323334353637 rt2contents -+ -+Block after ldxp/stxp 2x32-bit (success) -+0x0001020304050607 -+0x1011121314151617 -+0xbbbb000077778888 -+0x3031323334353637 -+0x4041424344454647 -+0x5051525354555657 -+0x0000000024252627 rt1contents -+0x0000000020212223 rt2contents -+ -diff --git a/none/tests/arm64/ldxp_stxp_fallbackimpl.vgtest b/none/tests/arm64/ldxp_stxp_fallbackimpl.vgtest -new file mode 100644 -index 000000000..474282a03 ---- /dev/null -+++ b/none/tests/arm64/ldxp_stxp_fallbackimpl.vgtest -@@ -0,0 +1,2 @@ -+prog: ldxp_stxp -+vgopts: -q --sim-hints=fallback-llsc - -commit 0d38ca5dd6b446c70738031132d41f09de0f7a8a -Author: Julian Seward -Date: Fri Nov 12 13:08:45 2021 +0100 - - Bug 444399 - disInstr(arm64): unhandled instruction 0xC87F2D89 (LD{,A}XP and ST{,L}XP). FOLLOWUP FIX. - - This is an attempt to un-break 'make dist', as broken by the main commit for - this bug, which was 530df882b8f60ecacaf2b9b8a719f7ea1c1d1650. - -diff --git a/none/tests/arm64/Makefile.am b/none/tests/arm64/Makefile.am -index 9efb49b27..4a06f0996 100644 ---- a/none/tests/arm64/Makefile.am -+++ b/none/tests/arm64/Makefile.am -@@ -14,8 +14,10 @@ EXTRA_DIST = \ - fmadd_sub.stdout.exp fmadd_sub.stderr.exp fmadd_sub.vgtest \ - fp_and_simd_v82.stdout.exp fp_and_simd_v82.stderr.exp \ - fp_and_simd_v82.vgtest \ -- ldxp_stxp.stdout.exp ldxp_stxp.stderr.exp \ -- ldxp_stxp_basisimpl.vgtest ldxp_stxp_fallbackimpl.vgtest -+ ldxp_stxp_basisimpl.stdout.exp ldxp_stxp_basisimpl.stderr.exp \ -+ ldxp_stxp_basisimpl.vgtest \ -+ ldxp_stxp_fallbackimpl.stdout.exp ldxp_stxp_fallbackimpl.stderr.exp \ -+ ldxp_stxp_fallbackimpl.vgtest - - check_PROGRAMS = \ - allexec \ diff --git a/SOURCES/valgrind-3.18.1-condvar.patch b/SOURCES/valgrind-3.18.1-condvar.patch deleted file mode 100644 index e129326..0000000 --- a/SOURCES/valgrind-3.18.1-condvar.patch +++ /dev/null @@ -1,284 +0,0 @@ -commit 9abfed23c0d430aafb85de6397d171316c982792 -Author: Paul Floyd -Date: Fri Nov 19 08:34:53 2021 +0100 - - Bug 445504 Using C++ condition_variable results in bogus "mutex is locked simultaneously by two threads" warning(edit) - - Add intercepts for pthread_cond_clockwait to DRD and Helgrind - Also testcase from bugzilla done by Bart, with configure check - -diff --git a/configure.ac b/configure.ac -index e7381f205..cb836dbff 100755 ---- a/configure.ac -+++ b/configure.ac -@@ -1989,6 +1989,27 @@ AC_LANG(C) - - AM_CONDITIONAL(CXX_CAN_INCLUDE_THREAD_HEADER, test x$ac_cxx_can_include_thread_header = xyes) - -+# Check whether compiler can process #include without errors -+ -+AC_MSG_CHECKING([that C++ compiler can include header file]) -+AC_LANG(C++) -+safe_CXXFLAGS=$CXXFLAGS -+CXXFLAGS=-std=c++0x -+ -+AC_COMPILE_IFELSE([AC_LANG_SOURCE([ -+#include -+])], -+[ -+ac_cxx_can_include_condition_variable_header=yes -+AC_MSG_RESULT([yes]) -+], [ -+ac_cxx_can_include_condition_variable_header=no -+AC_MSG_RESULT([no]) -+]) -+CXXFLAGS=$safe_CXXFLAGS -+AC_LANG(C) -+ -+AM_CONDITIONAL(CXX_CAN_INCLUDE_CONDITION_VARIABLE_HEADER, test x$ac_cxx_can_include_condition_variable_header = xyes) - - # On aarch64 before glibc 2.20 we would get the kernel user_pt_regs instead - # of the user_regs_struct from sys/user.h. They are structurally the same -diff --git a/drd/drd_pthread_intercepts.c b/drd/drd_pthread_intercepts.c -index 8b4454364..95127b42c 100644 ---- a/drd/drd_pthread_intercepts.c -+++ b/drd/drd_pthread_intercepts.c -@@ -1175,6 +1175,30 @@ PTH_FUNCS(int, condZureltimedwait, pthread_cond_timedwait_intercept, - (cond, mutex, timeout)); - #endif /* VGO_solaris */ - -+ -+static __always_inline -+int pthread_cond_clockwait_intercept(pthread_cond_t *cond, -+ pthread_mutex_t *mutex, -+ clockid_t clockid, -+ const struct timespec* abstime) -+{ -+ int ret; -+ OrigFn fn; -+ VALGRIND_GET_ORIG_FN(fn); -+ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__PRE_COND_WAIT, -+ cond, mutex, DRD_(mutex_type)(mutex), 0, 0); -+ CALL_FN_W_WWWW(ret, fn, cond, mutex, clockid, abstime); -+ VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__POST_COND_WAIT, -+ cond, mutex, 1, 0, 0); -+ return ret; -+} -+ -+PTH_FUNCS(int, pthreadZucondZuclockwait, pthread_cond_clockwait_intercept, -+ (pthread_cond_t *cond, pthread_mutex_t *mutex, -+ clockid_t clockid, const struct timespec* abstime), -+ (cond, mutex, clockid, abstime)); -+ -+ - // NOTE: be careful to intercept only pthread_cond_signal() and not Darwin's - // pthread_cond_signal_thread_np(). The former accepts one argument; the latter - // two. Intercepting all pthread_cond_signal* functions will cause only one -diff --git a/drd/tests/Makefile.am b/drd/tests/Makefile.am -index 4cb2f7f84..c804391e8 100755 ---- a/drd/tests/Makefile.am -+++ b/drd/tests/Makefile.am -@@ -105,6 +105,8 @@ EXTRA_DIST = \ - circular_buffer.vgtest \ - concurrent_close.stderr.exp \ - concurrent_close.vgtest \ -+ condvar.stderr.exp \ -+ condvar.vgtest \ - custom_alloc.stderr.exp \ - custom_alloc.vgtest \ - custom_alloc_fiw.stderr.exp \ -@@ -458,6 +460,11 @@ check_PROGRAMS += \ - endif - endif - -+if CXX_CAN_INCLUDE_CONDITION_VARIABLE_HEADER -+check_PROGRAMS += \ -+ condvar -+endif -+ - if HAVE_OPENMP - check_PROGRAMS += omp_matinv omp_prime omp_printf - endif -@@ -502,6 +509,8 @@ LDADD = -lpthread - - - bug322621_SOURCES = bug322621.cpp -+condvar_SOURCES = condvar.cpp -+condvar_CXXFLAGS = $(AM_CXXFLAGS) -std=c++0x - concurrent_close_SOURCES = concurrent_close.cpp - if !VGCONF_OS_IS_FREEBSD - dlopen_main_LDADD = -ldl -diff --git a/drd/tests/condvar.cpp b/drd/tests/condvar.cpp -new file mode 100644 -index 000000000..18ecb3f8a ---- /dev/null -+++ b/drd/tests/condvar.cpp -@@ -0,0 +1,55 @@ -+/* See also https://bugs.kde.org/show_bug.cgi?id=445504 */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+using lock_guard = std::lock_guard; -+using unique_lock = std::unique_lock; -+ -+struct state { -+ std::mutex m; -+ std::vector v; -+ std::condition_variable cv; -+ -+ state() { -+ // Call pthread_cond_init() explicitly to let DRD know about 'cv'. -+ pthread_cond_init(cv.native_handle(), NULL); -+ } -+}; -+ -+void other_thread(state *sp) { -+ state &s = *sp; -+ std::cerr << "Other thread: waiting for notify\n"; -+ unique_lock l{s.m}; -+ while (true) { -+ if (s.cv.wait_for(l, std::chrono::seconds(3)) != -+ std::cv_status::timeout) { -+ std::cerr << "Other thread: notified\n"; -+ break; -+ } -+ } -+ return; -+} -+ -+ -+int main() { -+ state s; -+ auto future = std::async(std::launch::async, other_thread, &s); -+ -+ if (future.wait_for(std::chrono::seconds(1)) != std::future_status::timeout) { -+ std::cerr << "Main: other thread returned too early!\n"; -+ return 2; -+ } -+ -+ { -+ std::lock_guard g{s.m}; -+ s.v.push_back(1); -+ s.v.push_back(2); -+ s.cv.notify_all(); -+ } -+ return 0; -+} -diff --git a/drd/tests/condvar.stderr.exp b/drd/tests/condvar.stderr.exp -new file mode 100644 -index 000000000..be1de9f97 ---- /dev/null -+++ b/drd/tests/condvar.stderr.exp -@@ -0,0 +1,5 @@ -+ -+Other thread: waiting for notify -+Other thread: notified -+ -+ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) -diff --git a/drd/tests/condvar.vgtest b/drd/tests/condvar.vgtest -new file mode 100644 -index 000000000..2e7d49f5a ---- /dev/null -+++ b/drd/tests/condvar.vgtest -@@ -0,0 +1,3 @@ -+prereq: ./supported_libpthread && [ -e condvar ] -+vgopts: --check-stack-var=yes --read-var-info=yes -+prog: condvar -diff --git a/helgrind/hg_intercepts.c b/helgrind/hg_intercepts.c -index 866efdbaa..49c3ddcd9 100644 ---- a/helgrind/hg_intercepts.c -+++ b/helgrind/hg_intercepts.c -@@ -1409,6 +1409,88 @@ static int pthread_cond_timedwait_WRK(pthread_cond_t* cond, - # error "Unsupported OS" - #endif - -+//----------------------------------------------------------- -+// glibc: pthread_cond_clockwait -+// -+__attribute__((noinline)) -+static int pthread_cond_clockwait_WRK(pthread_cond_t* cond, -+ pthread_mutex_t* mutex, -+ clockid_t clockid, -+ struct timespec* abstime, -+ int timeout_error) -+{ -+ int ret; -+ OrigFn fn; -+ unsigned long mutex_is_valid; -+ Bool abstime_is_valid; -+ VALGRIND_GET_ORIG_FN(fn); -+ -+ if (TRACE_PTH_FNS) { -+ fprintf(stderr, "<< pthread_cond_clockwait %p %p %p", -+ cond, mutex, abstime); -+ fflush(stderr); -+ } -+ -+ /* Tell the tool a cond-wait is about to happen, so it can check -+ for bogus argument values. In return it tells us whether it -+ thinks the mutex is valid or not. */ -+ DO_CREQ_W_WW(mutex_is_valid, -+ _VG_USERREQ__HG_PTHREAD_COND_WAIT_PRE, -+ pthread_cond_t*,cond, pthread_mutex_t*,mutex); -+ assert(mutex_is_valid == 1 || mutex_is_valid == 0); -+ -+ abstime_is_valid = abstime->tv_nsec >= 0 && abstime->tv_nsec < 1000000000; -+ -+ /* Tell the tool we're about to drop the mutex. This reflects the -+ fact that in a cond_wait, we show up holding the mutex, and the -+ call atomically drops the mutex and waits for the cv to be -+ signalled. */ -+ if (mutex_is_valid && abstime_is_valid) { -+ DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_PRE, -+ pthread_mutex_t*,mutex); -+ } -+ -+ CALL_FN_W_WWWW(ret, fn, cond,mutex,clockid,abstime); -+ -+ if (mutex_is_valid && !abstime_is_valid && ret != EINVAL) { -+ DO_PthAPIerror("Bug in libpthread: pthread_cond_clockwait " -+ "invalid abstime did not cause" -+ " EINVAL", ret); -+ } -+ -+ if (mutex_is_valid && abstime_is_valid) { -+ /* and now we have the mutex again if (ret == 0 || ret == timeout) */ -+ DO_CREQ_v_WW(_VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_POST, -+ pthread_mutex_t *, mutex, -+ long, (ret == 0 || ret == timeout_error) ? True : False); -+ } -+ -+ DO_CREQ_v_WWWW(_VG_USERREQ__HG_PTHREAD_COND_WAIT_POST, -+ pthread_cond_t*,cond, pthread_mutex_t*,mutex, -+ long,ret == timeout_error, -+ long, (ret == 0 || ret == timeout_error) && mutex_is_valid -+ ? True : False); -+ -+ if (ret != 0 && ret != timeout_error) { -+ DO_PthAPIerror( "pthread_cond_clockwait", ret ); -+ } -+ -+ if (TRACE_PTH_FNS) { -+ fprintf(stderr, " cotimedwait -> %d >>\n", ret); -+ } -+ -+ return ret; -+} -+ -+#if defined(VGO_linux) -+ PTH_FUNC(int, pthreadZucondZuclockwait, // pthread_cond_clockwait -+ pthread_cond_t* cond, pthread_mutex_t* mutex, -+ clockid_t clockid, -+ struct timespec* abstime) { -+ return pthread_cond_clockwait_WRK(cond, mutex, clockid, abstime, ETIMEDOUT); -+ } -+#endif -+ - - //----------------------------------------------------------- - // glibc: pthread_cond_signal@GLIBC_2.0 diff --git a/SOURCES/valgrind-3.18.1-demangle-namespace.patch b/SOURCES/valgrind-3.18.1-demangle-namespace.patch deleted file mode 100644 index 25ddf92..0000000 --- a/SOURCES/valgrind-3.18.1-demangle-namespace.patch +++ /dev/null @@ -1,35 +0,0 @@ -commit 542447d4708d4418a08e678dcf467af92b90b7ad -Author: Mark Wielaard -Date: Mon Nov 22 13:07:59 2021 +0100 - - readdwarf3.c (parse_inl_DIE) inlined_subroutine can appear in namespaces - - This was broken by commit 75e3ef0f3 "readdwarf3: Skip units without - addresses when looking for inlined functions". Specifically by this - part: "Also use skip_DIE instead of read_DIE when not parsing - (skipping) children" - - rustc puts concrete function instances in namespaces (which is - allowed in DWARF since there is no strict separation between type - declarations and program scope entries in a DIE tree), the inline - parser didn't expect this and so skipped any DIE under a namespace - entry. This wasn't an issue before because "skipping" a DIE tree was - done by reading it, so it wasn't actually skipped. But now that we - really skip the DIE (sub)tree (which is faster than actually parsing - it) some entries were missed in the rustc case. - - https://bugs.kde.org/show_bug.cgi?id=445668 - -diff --git a/coregrind/m_debuginfo/readdwarf3.c b/coregrind/m_debuginfo/readdwarf3.c -index 18eecea9f..5489f8d13 100644 ---- a/coregrind/m_debuginfo/readdwarf3.c -+++ b/coregrind/m_debuginfo/readdwarf3.c -@@ -3358,7 +3358,7 @@ static Bool parse_inl_DIE ( - // might maybe contain a DW_TAG_inlined_subroutine: - Bool ret = (unit_has_addrs - || dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram -- || dtag == DW_TAG_inlined_subroutine); -+ || dtag == DW_TAG_inlined_subroutine || dtag == DW_TAG_namespace); - return ret; - - bad_DIE: diff --git a/SOURCES/valgrind-3.18.1-dhat-tests-copy.patch b/SOURCES/valgrind-3.18.1-dhat-tests-copy.patch deleted file mode 100644 index 8e183b9..0000000 --- a/SOURCES/valgrind-3.18.1-dhat-tests-copy.patch +++ /dev/null @@ -1,20 +0,0 @@ -commit 33aba8eef68b1745d3de96b609ff8296b70d9a1c -Author: Paul Floyd -Date: Wed Oct 27 21:37:00 2021 +0200 - - Bug 444495 - dhat/tests/copy fails on s390x - - Add -fno-builtin to ensure that the copy functions get called and so dhat - can intercept and count them. - -diff --git a/dhat/tests/Makefile.am b/dhat/tests/Makefile.am -index 86a9b6d64..b86fc416d 100644 ---- a/dhat/tests/Makefile.am -+++ b/dhat/tests/Makefile.am -@@ -29,3 +29,6 @@ AM_CXXFLAGS += $(AM_FLAG_M3264_PRI) - # We don't care about uninitialized or unused malloc results - basic_CFLAGS = $(AM_CFLAGS) -Wno-uninitialized - big_CFLAGS = $(AM_CFLAGS) -Wno-unused-result -+ -+# Prevent the copying functions from being inlined -+copy_CFLAGS = $(AM_CFLAGS) -fno-builtin diff --git a/SOURCES/valgrind-3.18.1-gdbserver_tests-hwcap.patch b/SOURCES/valgrind-3.18.1-gdbserver_tests-hwcap.patch deleted file mode 100644 index 2d952cd..0000000 --- a/SOURCES/valgrind-3.18.1-gdbserver_tests-hwcap.patch +++ /dev/null @@ -1,25 +0,0 @@ -commit 64ab89162906d5b9e2de6c3afe476fec861ef7ec -Author: Mark Wielaard -Date: Tue Nov 2 14:27:45 2021 +0100 - - gdbserver_tests: Filter out glibc hwcaps libc.so - - On some systems the gdbserver_tests would fail because the filter - for the optimized hwcaps subdir didn't match because the file is - called slightly differently, with the version number before .so - instead of after. For example: /lib64/glibc-hwcaps/power9/libc-2.28.so - - Add one extra filter for this pattern. - -diff --git a/gdbserver_tests/filter_gdb.in b/gdbserver_tests/filter_gdb.in -index d0c94f3f1..b753e0168 100755 ---- a/gdbserver_tests/filter_gdb.in -+++ b/gdbserver_tests/filter_gdb.in -@@ -134,6 +134,7 @@ s/in \(.__\)\{0,1\}select () from \/.*$/in syscall .../ - /^ from \/lib\/libc.so.*$/d - /^ from \/lib64\/libc.so.*$/d - /^ from \/lib64\/.*\/libc.so.*$/d -+/^ from \/lib64\/.*\/libc-.*.so/d - - # and yet another (gdb 7.0 way) to get a system call - s/in select ()$/in syscall .../ diff --git a/SOURCES/valgrind-3.18.1-ppc-pstq-tests.patch b/SOURCES/valgrind-3.18.1-ppc-pstq-tests.patch deleted file mode 100644 index 58498f2..0000000 --- a/SOURCES/valgrind-3.18.1-ppc-pstq-tests.patch +++ /dev/null @@ -1,1876 +0,0 @@ -commit 3950c5d661ee09526cddcf24daf5fc22bc83f70c -Author: Carl Love -Date: Mon Nov 1 11:18:32 2021 -0500 - - Valgrind Add powerpc R=1 tests - - Contributed by Will Schmidt - - This includes updates and adjustments as suggested by Carl. - - Add tests that exercise PCRelative instructions. - These instructions are encoded with R==1, which indicate that - the memory accessed by the instruction is at a location - relative to the currently executing instruction. - - These tests are built using -Wl,-text and -Wl,-bss - options to ensure the location of the target array is at a - location with a specific offset from the currently - executing instruction. - - The write instructions are aimed at a large buffer in - the bss section; which is checked for updates at the - completion of each test. - - In order to ensure consistent output across assorted - systems, the tests have been padded with ori, nop instructions - and align directives. - - Detailed changes: - * Makefile.am: Add test_isa_3_1_R1_RT and test_isa_3_1_R1_XT tests. - * isa_3_1_helpers.h: Add identify_instruction_by_func_name() helper function - to indicate if the test is for R==1. - Add helpers to initialize and print changes to the pcrelative_write_target - array. - Add #define to help pad code with a series of eyecatcher ORI instructions. - * test_isa_3_1_R1_RT.c: New test. - * test_isa_3_1_R1_XT.c: New test. - * test_isa_3_1_R1_XT.stdout.exp: New expected output. - * test_isa_3_1_R1_XT.stdout.exp: New expected output. - * test_isa_3_1_R1_RT.stderr.exp: New expected output. - * test_isa_3_1_R1_RT.stderr.exp: New expected output. - - * test_isa_3_1_R1_RT.vgtest: New test handler. - * test_isa_3_1_R1_XT.vgtest: New test handler. - - * test_isa_3_1_common.c: Add indicators (updates_byte,updates_halfword, - updates_word) indicators to control the output from the R==1 tests. - Add helper check for "_R1" to indicate if instruction is coded with R==1. - Add init and print helpers for the pcrelative_write_target array. - -diff --git a/none/tests/ppc64/Makefile.am b/none/tests/ppc64/Makefile.am -index b709f3ef4..f8eab9fc0 100644 ---- a/none/tests/ppc64/Makefile.am -+++ b/none/tests/ppc64/Makefile.am -@@ -61,6 +61,8 @@ EXTRA_DIST = \ - test_isa_3_1_VRT.vgtest test_isa_3_1_VRT.stderr.exp test_isa_3_1_VRT.stdout.exp \ - test_isa_3_1_Misc.vgtest test_isa_3_1_Misc.stderr.exp test_isa_3_1_Misc.stdout.exp \ - test_isa_3_1_AT.vgtest test_isa_3_1_AT.stderr.exp test_isa_3_1_AT.stdout.exp \ -+ test_isa_3_1_R1_RT.vgtest test_isa_3_1_R1_RT.stderr.exp test_isa_3_1_R1_RT.stdout.exp \ -+ test_isa_3_1_R1_XT.vgtest test_isa_3_1_R1_XT.stderr.exp test_isa_3_1_R1_XT.stdout.exp \ - subnormal_test.stderr.exp subnormal_test.stdout.exp \ - subnormal_test.vgtest test_darn_inst.stderr.exp \ - test_darn_inst.stdout.exp test_darn_inst.vgtest \ -@@ -68,8 +70,8 @@ EXTRA_DIST = \ - test_copy_paste.stderr.exp test_copy_paste.stdout.exp \ - test_copy_paste.vgtest \ - test_mcrxrx.vgtest test_mcrxrx.stderr.exp test_mcrxrx.stdout.exp \ -- test_lxvx_stxvx.vgtest test_lxvx_stxvx.stderr.exp test_lxvx_stxvx.stdout.exp-p8 test_lxvx_stxvx.stdout.exp-p9 -- -+ test_lxvx_stxvx.vgtest test_lxvx_stxvx.stderr.exp \ -+ test_lxvx_stxvx.stdout.exp-p8 test_lxvx_stxvx.stdout.exp-p9 - - check_PROGRAMS = \ - allexec \ -@@ -80,11 +82,12 @@ check_PROGRAMS = \ - test_isa_3_0 test_mod_instructions \ - test_isa_3_1_RT test_isa_3_1_XT test_isa_3_1_VRT \ - test_isa_3_1_Misc test_isa_3_1_AT \ -+ test_isa_3_1_R1_RT test_isa_3_1_R1_XT \ - subnormal_test test_darn_inst test_copy_paste \ - test_tm test_touch_tm data-cache-instructions \ - std_reg_imm \ - twi_tdi tw_td power6_bcmp scv_test \ -- test_mcrxrx test_lxvx_stxvx -+ test_mcrxrx test_lxvx_stxvx - - # lmw, stmw, lswi, lswx, stswi, stswx compile (and run) only on big endian. - if VGCONF_PLATFORMS_INCLUDE_PPC64BE_LINUX -@@ -106,6 +109,8 @@ test_isa_3_1_RT_SOURCES = test_isa_3_1_RT.c test_isa_3_1_common.c - test_isa_3_1_VRT_SOURCES = test_isa_3_1_VRT.c test_isa_3_1_common.c - test_isa_3_1_Misc_SOURCES = test_isa_3_1_Misc.c test_isa_3_1_common.c - test_isa_3_1_AT_SOURCES = test_isa_3_1_AT.c test_isa_3_1_common.c -+test_isa_3_1_R1_XT_SOURCES = test_isa_3_1_R1_XT.c test_isa_3_1_common.c -+test_isa_3_1_R1_RT_SOURCES = test_isa_3_1_R1_RT.c test_isa_3_1_common.c - test_darn_inst_SOURCES = test_darn_inst.c - - if HAS_ALTIVEC -@@ -224,6 +229,11 @@ test_isa_3_1_VRT_CFLAGS = $(test_isa_3_1_CFLAGS) - test_isa_3_1_Misc_CFLAGS = $(test_isa_3_1_CFLAGS) - test_isa_3_1_AT_CFLAGS = $(test_isa_3_1_CFLAGS) - -+# The _R1_foo tests exercise pc-relative instructions, so require the bss and text sections -+# exist at known offsets with respect to each other. -+test_isa_3_1_R1_RT_CFLAGS = $(test_isa_3_1_CFLAGS) -Wl,-Tbss,0x20000 -Wl,-Ttext,0x40000 -+test_isa_3_1_R1_XT_CFLAGS = $(test_isa_3_1_CFLAGS) -Wl,-Tbss,0x20000 -Wl,-Ttext,0x40000 -+ - subnormal_test_CFLAGS = $(AM_CFLAGS) -Winline -Wall -O -g -mregnames $(VSX_FLAG) $(ISA_2_06_FLAG) \ - @FLAG_M64@ $(ALTIVEC_FLAG) $(BUILD_FLAG_VSX) $(BUILD_FLAGS_ISA_2_06) - -diff --git a/none/tests/ppc64/isa_3_1_helpers.h b/none/tests/ppc64/isa_3_1_helpers.h -index 338f55526..716a6277b 100644 ---- a/none/tests/ppc64/isa_3_1_helpers.h -+++ b/none/tests/ppc64/isa_3_1_helpers.h -@@ -43,6 +43,9 @@ extern void debug_show_current_iteration(); - extern void debug_dump_buffer(); - - extern void identify_form_components(const char *, const char *); -+extern void identify_instruction_by_func_name(const char *); -+extern void init_pcrelative_write_target(); -+extern void print_pcrelative_write_target(); - extern void dump_vsxargs(); - extern void generic_prologue(); - extern void build_args_table(); -@@ -58,6 +61,21 @@ extern void initialize_source_registers(); - extern void set_up_iterators(); - extern void initialize_buffer(int); - -+/* This (TEXT_BSS_DELTA) is the relative distance between those -+ sections as set by the linker options for the R==1 tests. */ -+#define TEXT_BSS_DELTA 0x20000 -+#define RELOC_BUFFER_SIZE 0x1000 -+extern unsigned long long pcrelative_buff_addr(int); -+#define PAD_ORI \ -+ __asm__ __volatile__ ("ori 21,21,21"); \ -+ __asm__ __volatile__ ("ori 22,22,22");\ -+ __asm__ __volatile__ ("ori 23,23,23");\ -+ __asm__ __volatile__ ("ori 24,24,24");\ -+ __asm__ __volatile__ ("ori 25,25,25");\ -+ __asm__ __volatile__ ("ori 26,26,26");\ -+ __asm__ __volatile__ ("ori 27,27,27");\ -+ __asm__ __volatile__ ("ori 28,28,28"); -+ - extern int verbose; - #define debug_printf(X) if (verbose>0) printf(X); - #define debug_show_labels (verbose>0) -diff --git a/none/tests/ppc64/test_isa_3_1_R1_RT.c b/none/tests/ppc64/test_isa_3_1_R1_RT.c -new file mode 100644 -index 000000000..d73b84b10 ---- /dev/null -+++ b/none/tests/ppc64/test_isa_3_1_R1_RT.c -@@ -0,0 +1,624 @@ -+/* -+ * Valgrind testcase for PowerPC ISA 3.1 -+ * -+ * Copyright (C) 2019-2020 Will Schmidt -+ * -+ * 64bit build: -+ * gcc -Winline -Wall -g -O -mregnames -maltivec -m64 -+ */ -+ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#include -+#ifdef HAS_ISA_3_1 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+/* Condition Register fields. -+ These are used to capture the condition register values immediately after -+ the instruction under test is executed. This is done to help prevent other -+ test overhead (switch statements, result compares, etc) from disturbing -+ the test case results. */ -+unsigned long current_cr; -+unsigned long current_fpscr; -+ -+struct test_list_t current_test; -+ -+#include "isa_3_1_helpers.h" -+ -+static void test_plxvp_off0_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plxvp 20, +0(0),1" ); -+ PAD_ORI -+} -+static void test_plxvp_off8_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plxvp 20, +8(0),1" ); -+ PAD_ORI -+} -+static void test_plxvp_off16_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plxvp 20, +16(0),1" ); -+ PAD_ORI -+} -+static void test_plxvp_off24_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plxvp 20, +24(0),1" ); -+ PAD_ORI -+} -+static void test_plxvp_off32_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plxvp 20, +32(0),1" ); -+ PAD_ORI -+} -+static void test_plbz_off0_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plbz %0, +0(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plbz_off8_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plbz %0, +8(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plbz_off16_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plbz %0, +16(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plbz_off32_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plbz %0, +32(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plbz_off64_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plbz %0, +64(0), 1" : "=r" (rt) ); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_plhz_off0_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plhz %0, +0(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plhz_off8_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plhz %0, +8(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plhz_off16_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plhz %0, +16(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plhz_off32_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plhz %0, +32(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plhz_off64_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plhz %0, +64(0), 1" : "=r" (rt) ); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_plha_off0_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plha %0, +0(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plha_off8_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plha %0, +8(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plha_off16_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plha %0, +16(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plha_off32_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plha %0, +32(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plha_off64_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plha %0, +64(0), 1" : "=r" (rt) ); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_plwz_off0_R1 (void) { -+ __asm__ __volatile__ ("plwz %0, +0(0), 1" : "=r" (rt) ); -+} -+static void test_plwz_off8_R1 (void) { -+ __asm__ __volatile__ ("plwz %0, +8(0), 1" : "=r" (rt) ); -+} -+static void test_plwz_off16_R1 (void) { -+ __asm__ __volatile__ ("plwz %0, +16(0), 1" : "=r" (rt) ); -+} -+static void test_plwz_off32_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plwz %0, +32(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plwz_off64_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plwz %0, +64(0), 1" : "=r" (rt) ); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_plwa_off0_R1 (void) { -+ __asm__ __volatile__ ("plwa %0, +0(0), 1" : "=r" (rt) ); -+} -+static void test_plwa_off8_R1 (void) { -+ __asm__ __volatile__ ("plwa %0, +8(0), 1" : "=r" (rt) ); -+} -+static void test_plwa_off16_R1 (void) { -+ __asm__ __volatile__ ("plwa %0, +16(0), 1" : "=r" (rt) ); -+} -+static void test_plwa_off32_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plwa %0, +32(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_plwa_off64_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plwa %0, +64(0), 1" : "=r" (rt) ); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_pld_off0_R1 (void) { -+ __asm__ __volatile__ ("pld %0, +0(0), 1" : "=r" (rt) ); -+} -+static void test_pld_off8_R1 (void) { -+ __asm__ __volatile__ ("pld %0, +8(0), 1" : "=r" (rt) ); -+} -+static void test_pld_off16_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("pld %0, +16(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_pld_off32_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("pld %0, +32(0), 1" : "=r" (rt) ); -+ PAD_ORI -+} -+static void test_pld_off64_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("pld %0, +64(0), 1" : "=r" (rt) ); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_pstb_off0_R1 (void) { -+ __asm__ __volatile__ ("pstb %0, -0x1f400+0(0), 1" :: "r" (rs) ); -+} -+static void test_pstb_off8_R1 (void) { -+ __asm__ __volatile__ ("pstb %0, -0x1f400+8(0), 1" :: "r" (rs) ); -+} -+static void test_pstb_off16_R1 (void) { -+ __asm__ __volatile__ ("pstb %0, -0x1f400+16(0), 1" :: "r" (rs) ); -+} -+static void test_pstb_off32_R1 (void) { -+ __asm__ __volatile__ ("pstb %0, -0x1f400+32(0), 1" :: "r" (rs) ); -+} -+static void test_psth_off0_R1 (void) { -+ __asm__ __volatile__ ("psth %0, -0x1f400+0(0), 1" :: "r" (rs) ); -+} -+static void test_psth_off8_R1 (void) { -+ __asm__ __volatile__ ("psth %0, -0x1f400+8(0), 1" :: "r" (rs) ); -+} -+static void test_psth_off16_R1 (void) { -+ __asm__ __volatile__ ("psth %0, -0x1f400+16(0), 1" :: "r" (rs) ); -+} -+static void test_psth_off32_R1 (void) { -+ __asm__ __volatile__ ("psth %0, -0x1f400+32(0), 1" :: "r" (rs) ); -+} -+static void test_pstw_off0_R1 (void) { -+ __asm__ __volatile__ ("pstw %0, -0x1f400+0(0), 1" :: "r" (rs) ); -+} -+static void test_pstw_off8_R1 (void) { -+ __asm__ __volatile__ ("pstw %0, -0x1f400+8(0), 1" :: "r" (rs) ); -+} -+static void test_pstw_off16_R1 (void) { -+ __asm__ __volatile__ ("pstw %0, -0x1f400+16(0), 1" :: "r" (rs) ); -+} -+static void test_pstw_off32_R1 (void) { -+ __asm__ __volatile__ ("pstw %0, -0x1f400+32(0), 1" :: "r" (rs) ); -+} -+static void test_pstd_off0_R1 (void) { -+ __asm__ __volatile__ ("pstd %0, -0x1f400+0(0), 1" :: "r" (rs) ); -+} -+static void test_pstd_off8_R1 (void) { -+ __asm__ __volatile__ ("pstd %0, -0x1f400+8(0), 1" :: "r" (rs) ); -+} -+static void test_pstd_off16_R1 (void) { -+ __asm__ __volatile__ ("pstd %0, -0x1f400+16(0), 1" :: "r" (rs) ); -+} -+static void test_pstd_off32_R1 (void) { -+ __asm__ __volatile__ ("pstd %0, -0x1f400+32(0), 1" :: "r" (rs) ); -+} -+ /* For the paddi tests; although we can get close to a read/write target -+ due to forcing where the .text and .bss sections are placed, there is -+ still enough codegen variability that having a raw value in the exp -+ file will not be determinative for these instructions. -+ Thus, compromise and just ensure that the generated value is an -+ address that lands within the reloc buffer, and use quasi magic -+ eyecatcher values in the return to indicate success. */ -+static void test_paddi_0_R1 (void) { -+ __asm__ __volatile__ ("paddi %0, 0, 0+0, 1" : "=r" (rt) ); -+ rt = rt - TEXT_BSS_DELTA; -+ if (rt > pcrelative_buff_addr(0) && -+ rt < pcrelative_buff_addr(RELOC_BUFFER_SIZE)) -+ rt = 0xffff0000; -+} -+static void test_paddi_12_R1 (void) { -+ __asm__ __volatile__ ("paddi %0, 0, 0+12, 1" : "=r" (rt) ); -+ rt = rt - TEXT_BSS_DELTA; -+ if (rt > pcrelative_buff_addr(0) && -+ rt < pcrelative_buff_addr(RELOC_BUFFER_SIZE)) -+ rt = 0xffff0012; -+} -+static void test_paddi_48_R1 (void) { -+ __asm__ __volatile__ ("paddi %0, 0, 0+48, 1" : "=r" (rt) ); -+ rt = rt - TEXT_BSS_DELTA; -+ if (rt > pcrelative_buff_addr(0) && -+ rt < pcrelative_buff_addr(RELOC_BUFFER_SIZE)) -+ rt = 0xffff0048; -+} -+static void test_paddi_98_R1 (void) { -+ __asm__ __volatile__ ("paddi %0, 0, 0+98, 1" : "=r" (rt) ); -+ rt = rt - TEXT_BSS_DELTA; -+ if (rt > pcrelative_buff_addr(0) && -+ rt < pcrelative_buff_addr(RELOC_BUFFER_SIZE)) -+ rt = 0xffff0098; -+} -+static void test_plq_off0_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plq 26, +0(0), 1" ); -+ PAD_ORI -+} -+static void test_plq_off8_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plq 26, +8(0), 1" ); -+ PAD_ORI -+} -+static void test_plq_off16_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plq 26, +16(0), 1" ); -+ PAD_ORI -+} -+static void test_plq_off32_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plq 26, +32(0), 1" ); -+ PAD_ORI -+} -+static void test_plq_off48_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plq 26, +48(0), 1" ); -+ PAD_ORI -+} -+static void test_plq_off64_R1 (void) { -+ PAD_ORI -+ __asm__ __volatile__ ("plq 26, +64(0), 1" ); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_pstq_off0_R1 (void) { -+ __asm__ __volatile__ ("pstq 24, -0x1f400+0(0), 1" ); -+} -+static void test_pstq_off8_R1 (void) { -+ __asm__ __volatile__ ("pstq 24, -0x1f400+8(0), 1" ); -+} -+static void test_pstq_off16_R1 (void) { -+ __asm__ __volatile__ ("pstq 24, -0x1f400+16(0), 1" ); -+} -+static void test_pstq_off32_R1 (void) { -+ __asm__ __volatile__ ("pstq 24, -0x1f400+32(0), 1" ); -+} -+static void test_pstq_off64_R1 (void) { -+ __asm__ __volatile__ ("pstq 24, -0x1f400+64(0), 1" ); -+} -+ -+static test_list_t testgroup_generic[] = { -+ { &test_paddi_0_R1, "paddi 0_R1", "RT,RA,SI,R"}, /* bcwp */ -+ { &test_paddi_12_R1, "paddi 12_R1", "RT,RA,SI,R"}, /* bcwp */ -+ { &test_paddi_48_R1, "paddi 48_R1", "RT,RA,SI,R"}, /* bcwp */ -+ { &test_paddi_98_R1, "paddi 98_R1", "RT,RA,SI,R"}, /* bcwp */ -+ { &test_plbz_off0_R1, "plbz off0_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plbz_off8_R1, "plbz off8_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plbz_off16_R1, "plbz off16_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plbz_off32_R1, "plbz off32_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plbz_off64_R1, "plbz off64_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_pld_off0_R1, "pld off0_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_pld_off8_R1, "pld off8_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_pld_off16_R1, "pld off16_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_pld_off32_R1, "pld off32_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_pld_off64_R1, "pld off64_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plha_off0_R1, "plha off0_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plha_off8_R1, "plha off8_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plha_off16_R1, "plha off16_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plha_off32_R1, "plha off32_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plha_off64_R1, "plha off64_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plhz_off0_R1, "plhz off0_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plhz_off8_R1, "plhz off8_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plhz_off16_R1, "plhz off16_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plhz_off32_R1, "plhz off32_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plhz_off64_R1, "plhz off64_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plq_off0_R1, "plq off0_R1", "RTp,D(RA),R"}, /* bcwp */ -+ { &test_plq_off8_R1, "plq off8_R1", "RTp,D(RA),R"}, /* bcwp */ -+ { &test_plq_off16_R1, "plq off16_R1", "RTp,D(RA),R"}, /* bcwp */ -+ { &test_plq_off32_R1, "plq off32_R1", "RTp,D(RA),R"}, /* bcwp */ -+ { &test_plq_off48_R1, "plq off48_R1", "RTp,D(RA),R"}, /* bcwp */ -+ { &test_plq_off64_R1, "plq off64_R1", "RTp,D(RA),R"}, /* bcwp */ -+ { &test_plwa_off0_R1, "plwa off0_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plwa_off8_R1, "plwa off8_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plwa_off16_R1, "plwa off16_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plwa_off32_R1, "plwa off32_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plwa_off64_R1, "plwa off64_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plwz_off0_R1, "plwz off0_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plwz_off8_R1, "plwz off8_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plwz_off16_R1, "plwz off16_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plwz_off32_R1, "plwz off32_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plwz_off64_R1, "plwz off64_R1", "RT,D(RA),R"}, /* bcwp */ -+ { &test_plxvp_off0_R1, "plxvp off0_R1", "XTp,D(RA),R"}, /* bcwp */ -+ { &test_plxvp_off8_R1, "plxvp off8_R1", "XTp,D(RA),R"}, /* bcwp */ -+ { &test_plxvp_off16_R1, "plxvp off16_R1", "XTp,D(RA),R"}, /* bcwp */ -+ { &test_plxvp_off24_R1, "plxvp off24_R1", "XTp,D(RA),R"}, /* bcwp */ -+ { &test_plxvp_off32_R1, "plxvp off32_R1", "XTp,D(RA),R"}, /* bcwp */ -+ { &test_pstb_off0_R1, "pstb off0_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstb_off8_R1, "pstb off8_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstb_off16_R1, "pstb off16_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstb_off32_R1, "pstb off32_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstd_off0_R1, "pstd off0_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstd_off8_R1, "pstd off8_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstd_off16_R1, "pstd off16_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstd_off32_R1, "pstd off32_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_psth_off0_R1, "psth off0_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_psth_off8_R1, "psth off8_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_psth_off16_R1, "psth off16_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_psth_off32_R1, "psth off32_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstq_off0_R1, "pstq off0_R1", "RSp,D(RA),R"}, /* bcwp */ -+ { &test_pstq_off8_R1, "pstq off8_R1", "RSp,D(RA),R"}, /* bcwp */ -+ { &test_pstq_off16_R1, "pstq off16_R1", "RSp,D(RA),R"}, /* bcwp */ -+ { &test_pstq_off32_R1, "pstq off32_R1", "RSp,D(RA),R"}, /* bcwp */ -+ { &test_pstq_off64_R1, "pstq off64_R1", "RSp,D(RA),R"}, /* bcwp */ -+ { &test_pstw_off0_R1, "pstw off0_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstw_off8_R1, "pstw off8_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstw_off16_R1, "pstw off16_R1", "RS,D(RA),R"}, /* bcwp */ -+ { &test_pstw_off32_R1, "pstw off32_R1", "RS,D(RA),R"}, /* bcwp */ -+ { NULL, NULL }, -+}; -+ -+/* Allow skipping of tests. */ -+unsigned long test_count=0xffff; -+unsigned long skip_count=0; -+unsigned long setup_only=0; -+ -+/* Set up a setjmp/longjmp to gently handle our SIGILLs and SIGSEGVs. */ -+static jmp_buf mybuf; -+ -+/* This (testfunction_generic) is meant to handle all of the instruction -+ variations. The helpers set up the register and iterator values -+ as is appropriate for the instruction being tested. */ -+static void testfunction_generic (const char* instruction_name, -+ test_func_t test_function, -+ unsigned int ignore_flags, -+ char * cur_form) { -+ -+ identify_form_components (instruction_name , cur_form); -+ debug_show_form (instruction_name, cur_form); -+ set_up_iterators (); -+ debug_show_iter_ranges (); -+ initialize_buffer (0); -+ init_pcrelative_write_target (); -+ debug_dump_buffer (); -+ -+ for (vrai = a_start; vrai < a_iters ; vrai+=a_inc) { -+ for (vrbi = b_start; vrbi < b_iters ; vrbi+=b_inc) { -+ for (vrci = c_start; vrci < c_iters ; vrci+=c_inc) { -+ for (vrmi = m_start; (vrmi < m_iters) ; vrmi+=m_inc) { -+ CHECK_OVERRIDES -+ debug_show_current_iteration (); -+ // Be sure to initialize the target registers first. -+ initialize_target_registers (); -+ initialize_source_registers (); -+ printf ("%s", instruction_name); -+ print_register_header (); -+ printf( " =>"); fflush (stdout); -+ if (!setup_only) { -+ if (enable_setjmp) { -+ if ( setjmp ( mybuf ) ) { -+ printf("signal tripped. (FIXME)\n"); -+ continue; -+ } -+ } -+ (*test_function) (); -+ } -+ print_register_footer (); -+ print_result_buffer (); -+ print_pcrelative_write_target (); -+ printf ("\n"); -+ } -+ } -+ } -+ } -+} -+ -+void mykillhandler ( int x ) { longjmp (mybuf, 1); } -+void mysegvhandler ( int x ) { longjmp (mybuf, 1); } -+ -+static void do_tests ( void ) -+{ -+ int groupcount; -+ char * cur_form; -+ test_group_t group_function = &testfunction_generic; -+ test_list_t *tests = testgroup_generic; -+ -+ struct sigaction kill_action, segv_action; -+ struct sigaction old_kill_action, old_segv_action; -+ if (enable_setjmp) { -+ kill_action.sa_handler = mykillhandler; -+ segv_action.sa_handler = mysegvhandler; -+ sigemptyset ( &kill_action.sa_mask ); -+ sigemptyset ( &segv_action.sa_mask ); -+ kill_action.sa_flags = SA_NODEFER; -+ segv_action.sa_flags = SA_NODEFER; -+ sigaction ( SIGILL, &kill_action, &old_kill_action); -+ sigaction ( SIGSEGV, &segv_action, &old_segv_action); -+ } -+ -+ for (groupcount = 0; tests[groupcount].name != NULL; groupcount++) { -+ cur_form = strdup(tests[groupcount].form); -+ current_test = tests[groupcount]; -+ identify_instruction_by_func_name (current_test.name); -+ if (groupcount < skip_count) continue; -+ if (verbose) printf("Test #%d ,", groupcount); -+ if (verbose > 1) printf(" instruction %s (v=%d)", current_test.name, verbose); -+ (*group_function) (current_test.name, current_test.func, 0, cur_form ); -+ printf ("\n"); -+ if (groupcount >= (skip_count+test_count)) break; -+ } -+ if (debug_show_labels) printf("\n"); -+ printf ("All done. Tested %d different instruction groups\n", groupcount); -+} -+ -+static void usage (void) -+{ -+ fprintf(stderr, -+ "Usage: test_isa_XXX [OPTIONS]\n" -+ "\t-h: display this help and exit\n" -+ "\t-v: increase verbosity\n" -+ "\t-a : limit number of a-iterations to \n" -+ "\t-b : limit number of b-iterations to \n" -+ "\t-c : limit number of c-iterations to \n" -+ "\t-n : limit to this number of tests.\n" -+ "\t-r : run only test # \n" -+ "\t\n" -+ "\t-j :enable setjmp to recover from illegal insns. \n" -+ "\t-m :(dev only?) lock VRM value to zero.\n" -+ "\t-z :(dev only?) lock MC value to zero.\n" -+ "\t-p :(dev only?) disable prefix instructions\n" -+ "\t-s : skip tests \n" -+ "\t-c : stop after running # of tests \n" -+ "\t-f : Do the test setup but do not actually execute the test instruction. \n" -+ ); -+} -+ -+int main (int argc, char **argv) -+{ -+ int c; -+ while ((c = getopt(argc, argv, "dhjvmpfzs:a:b:c:n:r:")) != -1) { -+ switch (c) { -+ case 'h': -+ usage(); -+ return 0; -+ -+ case 'v': -+ verbose++; -+ break; -+ -+ /* Options related to limiting the test iterations. */ -+ case 'a': -+ a_limit=atoi (optarg); -+ printf ("limiting a-iters to %ld.\n", a_limit); -+ break; -+ case 'b': -+ b_limit=atoi (optarg); -+ printf ("limiting b-iters to %ld.\n", b_limit); -+ break; -+ case 'c': -+ c_limit=atoi (optarg); -+ printf ("limiting c-iters to %ld.\n", c_limit); -+ break; -+ case 'n': // run this number of tests. -+ test_count=atoi (optarg); -+ printf ("limiting to %ld tests\n", test_count); -+ break; -+ case 'r': // run just test #. -+ skip_count=atoi (optarg); -+ test_count=0; -+ if (verbose) printf("Running test number %ld\n", skip_count); -+ break; -+ case 's': // skip this number of tests. -+ skip_count=atoi (optarg); -+ printf ("skipping %ld tests\n", skip_count); -+ break; -+ -+ /* debug options. */ -+ case 'd': -+ dump_tables=1; -+ printf("DEBUG:dump_tables.\n"); -+ break; -+ case 'f': -+ setup_only=1; -+ printf("DEBUG:setup_only.\n"); -+ break; -+ case 'j': -+ enable_setjmp=1; -+ printf ("DEBUG:setjmp enabled.\n"); -+ break; -+ case 'm': -+ vrm_override=1; -+ printf ("DEBUG:vrm override enabled.\n"); -+ break; -+ case 'p': -+ prefix_override=1; -+ printf ("DEBUG:prefix override enabled.\n"); -+ break; -+ case 'z': -+ mc_override=1; -+ printf ("DEBUG:MC override enabled.\n"); -+ break; -+ default: -+ usage(); -+ fprintf(stderr, "Unknown argument: '%c'\n", c); -+ } -+ } -+ -+ generic_prologue (); -+ build_vsx_table (); -+ build_args_table (); -+ build_float_vsx_tables (); -+ -+ if (dump_tables) { -+ dump_float_vsx_tables (); -+ dump_vsxargs (); -+ } -+ -+ do_tests (); -+ -+ return 0; -+} -+ -+#else // HAS_ISA_3_1 -+int main (int argc, char **argv) -+{ -+ printf("NO ISA 3.1 SUPPORT\n"); -+ return 0; -+} -+#endif -diff --git a/none/tests/ppc64/test_isa_3_1_R1_RT.stderr.exp b/none/tests/ppc64/test_isa_3_1_R1_RT.stderr.exp -new file mode 100644 -index 000000000..139597f9c ---- /dev/null -+++ b/none/tests/ppc64/test_isa_3_1_R1_RT.stderr.exp -@@ -0,0 +1,2 @@ -+ -+ -diff --git a/none/tests/ppc64/test_isa_3_1_R1_RT.stdout.exp b/none/tests/ppc64/test_isa_3_1_R1_RT.stdout.exp -new file mode 100644 -index 000000000..87594748f ---- /dev/null -+++ b/none/tests/ppc64/test_isa_3_1_R1_RT.stdout.exp -@@ -0,0 +1,138 @@ -+paddi 0_R1 => ffff0000 -+ -+paddi 12_R1 => ffff0012 -+ -+paddi 48_R1 => ffff0048 -+ -+paddi 98_R1 => ffff0098 -+ -+plbz off0_R1 => 1a -+ -+plbz off8_R1 => 1f -+ -+plbz off16_R1 => 1f -+ -+plbz off32_R1 => 1b -+ -+plbz off64_R1 => 1b -+ -+pld off0_R1 => e740000004100000 -+ -+pld off8_R1 => 4e800020 -+ -+pld off16_R1 => 6318001862f7001f -+ -+pld off32_R1 => 639c001c637b001b -+ -+pld off64_R1 => 639c001c637b001b -+ -+plha off0_R1 => 1a -+ -+plha off8_R1 => 1f -+ -+plha off16_R1 => 1f -+ -+plha off32_R1 => 1b -+ -+plha off64_R1 => 1b -+ -+plhz off0_R1 => 1a -+ -+plhz off8_R1 => 1f -+ -+plhz off16_R1 => 1f -+ -+plhz off32_R1 => 1b -+ -+plhz off64_R1 => 1b -+ -+plq off0_R1 => e34000000410001a 62d6001662b5001f -+ -+plq off8_R1 => 62d6001662b5001f 6318001862f7001f -+ -+plq off16_R1 => 6318001862f7001f 635a001a6339001b -+ -+plq off32_R1 => 639c001c637b001b 4e80003b -+ -+plq off48_R1 => 1a 62d6001662b5001f -+ -+plq off64_R1 => 639c001c637b001b 4e80003b -+ -+plwa off0_R1 => 4100000 -+ -+plwa off8_R1 => 4e800020 -+ -+plwa off16_R1 => 0 -+ -+plwa off32_R1 => 637b001b -+ -+plwa off64_R1 => 637b001b -+ -+plwz off0_R1 => 6100000 -+ -+plwz off8_R1 => 4e800020 -+ -+plwz off16_R1 => 0 -+ -+plwz off32_R1 => 637b001b -+ -+plwz off64_R1 => 637b001b -+ -+plxvp off0_R1 => 6318001862f70017 635a001a63390019 ea80000004100000 62d6001662b50015 -+ -+plxvp off8_R1 => 635a001a63390019 639c001c637b001b 62d6001662b50015 6318001862f70017 -+ -+plxvp off16_R1 => 639c001c637b001b 000000004e800020 6318001862f70017 635a001a63390019 -+ -+plxvp off24_R1 => 000000004e800020 0000000000000000 635a001a63390019 639c001c637b001b -+ -+plxvp off32_R1 => 0000000000000000 62d6001662b50015 639c001c637b001b 000000004e800020 -+ -+pstb off0_R1 102030405060708 => 08 -+ -+pstb off8_R1 102030405060708 => 08 -+ -+pstb off16_R1 102030405060708 => 08 -+ -+pstb off32_R1 102030405060708 => 08 -+ -+pstd off0_R1 102030405060708 => 0102030405060708 -+ -+pstd off8_R1 102030405060708 => 0102030405060708 -+ -+pstd off16_R1 102030405060708 => 0102030405060708 -+ -+pstd off32_R1 102030405060708 => 0102030405060708 -+ -+psth off0_R1 102030405060708 => 0708 -+ -+psth off8_R1 102030405060708 => 0708 -+ -+psth off16_R1 102030405060708 => 0708 -+ -+psth off32_R1 102030405060708 => 0708 -+ -+pstq off0_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708 a5b4c3d2e1f00918 -+pstq off0_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708 a5b4c3d2e1f00918 -+ -+pstq off8_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708 a5b4c3d2e1f00918 -+pstq off8_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708 a5b4c3d2e1f00918 -+ -+pstq off16_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708 a5b4c3d2e1f00918 -+pstq off16_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708 a5b4c3d2e1f00918 -+ -+pstq off32_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708 a5b4c3d2e1f00918 -+pstq off32_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708 a5b4c3d2e1f00918 -+ -+pstq off64_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708 a5b4c3d2e1f00918 -+pstq off64_R1 102030405060708 a5b4c3d2e1f00918 => 0102030405060708 a5b4c3d2e1f00918 -+ -+pstw off0_R1 102030405060708 => 05060708 -+ -+pstw off8_R1 102030405060708 => 05060708 -+ -+pstw off16_R1 102030405060708 => 05060708 -+ -+pstw off32_R1 102030405060708 => 05060708 -+ -+All done. Tested 66 different instruction groups -diff --git a/none/tests/ppc64/test_isa_3_1_R1_RT.vgtest b/none/tests/ppc64/test_isa_3_1_R1_RT.vgtest -new file mode 100644 -index 000000000..61d7f65a1 ---- /dev/null -+++ b/none/tests/ppc64/test_isa_3_1_R1_RT.vgtest -@@ -0,0 +1,2 @@ -+prereq: ../../../tests/check_ppc64_auxv_cap arch_3_1 -+prog: test_isa_3_1_R1_RT -diff --git a/none/tests/ppc64/test_isa_3_1_R1_XT.c b/none/tests/ppc64/test_isa_3_1_R1_XT.c -new file mode 100644 -index 000000000..58885b8d3 ---- /dev/null -+++ b/none/tests/ppc64/test_isa_3_1_R1_XT.c -@@ -0,0 +1,534 @@ -+/* -+ * Valgrind testcase for PowerPC ISA 3.1 -+ * -+ * Copyright (C) 2019-2020 Will Schmidt -+ * -+ * 64bit build: -+ * gcc -Winline -Wall -g -O -mregnames -maltivec -m64 -+ */ -+ -+/* -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of the -+ * License, or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#include -+#ifdef HAS_ISA_3_1 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+/* Condition Register fields. -+ These are used to capture the condition register values immediately after -+ the instruction under test is executed. This is done to help prevent other -+ test overhead (switch statements, result compares, etc) from disturbing -+ the test case results. */ -+unsigned long current_cr; -+unsigned long current_fpscr; -+ -+struct test_list_t current_test; -+ -+#include "isa_3_1_helpers.h" -+static void test_pstxvp_off0_R1 (void) { -+ __asm__ __volatile__ ("pstxvp 20, -0x1f400+0(0),1"); -+} -+static void test_pstxvp_off16_R1 (void) { -+ __asm__ __volatile__ ("pstxvp 20, -0x1f400+16(0),1"); -+} -+static void test_pstxvp_off32_R1 (void) { -+ __asm__ __volatile__ ("pstxvp 20, -0x1f400+32(0),1"); -+} -+static void test_pstxvp_off48_R1 (void) { -+ __asm__ __volatile__ ("pstxvp 20, -0x1f400+48(0),1"); -+} -+static void test_plfd_64_R1 (void) { -+ __asm__ __volatile__ ("plfd 28, +64(0), 1"); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_plfd_32_R1 (void) { -+ __asm__ __volatile__ ("plfd 28, +32(0), 1"); -+ PAD_ORI -+} -+static void test_plfd_16_R1 (void) { -+ __asm__ __volatile__ ("plfd 28, +16(0), 1"); -+ PAD_ORI -+} -+static void test_plfd_8_R1 (void) { -+ __asm__ __volatile__ ("plfd 28, +8(0), 1"); -+ PAD_ORI -+} -+static void test_plfd_4_R1 (void) { -+ __asm__ __volatile__ ("plfd 28, +4(0), 1"); -+ PAD_ORI -+} -+static void test_plfd_0_R1 (void) { -+ __asm__ __volatile__ ("plfd 28, +0(0), 1"); -+ PAD_ORI -+} -+static void test_plfs_64_R1 (void) { -+ __asm__ __volatile__ ("plfs 28, +64(0), 1"); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_plfs_32_R1 (void) { -+ __asm__ __volatile__ ("plfs 28, +32(0), 1"); -+ PAD_ORI -+} -+static void test_plfs_16_R1 (void) { -+ __asm__ __volatile__ ("plfs 28, +16(0), 1"); -+ PAD_ORI -+} -+static void test_plfs_8_R1 (void) { -+ __asm__ __volatile__ ("plfs 28, +8(0), 1"); -+ PAD_ORI -+} -+static void test_plfs_4_R1 (void) { -+ __asm__ __volatile__ ("plfs 28, +4(0), 1"); -+ PAD_ORI -+} -+static void test_plfs_0_R1 (void) { -+ __asm__ __volatile__ ("plfs 28, +0(0), 1"); -+ PAD_ORI -+} -+static void test_pstfd_32_R1 (void) { -+ __asm__ __volatile__ ("pstfd 26, -0x1f400+32(0), 1"); -+} -+static void test_pstfd_16_R1 (void) { -+ __asm__ __volatile__ ("pstfd 26, -0x1f400+16(0), 1"); -+} -+static void test_pstfd_8_R1 (void) { -+ __asm__ __volatile__ ("pstfd 26, -0x1f400+8(0), 1"); -+} -+static void test_pstfd_4_R1 (void) { -+ __asm__ __volatile__ ("pstfd 26, -0x1f400+4(0), 1"); -+} -+static void test_pstfd_0_R1 (void) { -+ __asm__ __volatile__ ("pstfd 26, -0x1f400+0(0), 1"); -+} -+static void test_pstfs_32_R1 (void) { -+ __asm__ __volatile__ ("pstfs 26, -0x1f400+32(0), 1"); -+} -+static void test_pstfs_16_R1 (void) { -+ __asm__ __volatile__ ("pstfs 26, -0x1f400+16(0), 1"); -+} -+static void test_pstfs_8_R1 (void) { -+ __asm__ __volatile__ ("pstfs 26, -0x1f400+8(0), 1"); -+} -+static void test_pstfs_4_R1 (void) { -+ __asm__ __volatile__ ("pstfs 26, -0x1f400+4(0), 1"); -+} -+static void test_pstfs_0_R1 (void) { -+ __asm__ __volatile__ ("pstfs 26, -0x1f400+0(0), 1"); -+} -+static void test_plxsd_64_R1 (void) { -+ __asm__ __volatile__ ("plxsd %0, +64(0), 1" : "=v" (vrt) ); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_plxsd_32_R1 (void) { -+ __asm__ __volatile__ (".align 2 ; plxsd %0, +32(0), 1" : "=v" (vrt) ); -+ PAD_ORI -+} -+static void test_plxsd_16_R1 (void) { -+ __asm__ __volatile__ ("plxsd %0, +16(0), 1; pnop;pnop;pnop; " : "=v" (vrt) ); -+ PAD_ORI -+} -+static void test_plxsd_8_R1 (void) { -+ __asm__ __volatile__ ("plxsd %0, +8(0), 1; pnop;pnop;pnop; " : "=v" (vrt) ); -+ PAD_ORI -+} -+static void test_plxsd_4_R1 (void) { -+ __asm__ __volatile__ ("plxsd %0, +4(0), 1; pnop;pnop;pnop; " : "=v" (vrt) ); -+ PAD_ORI -+} -+static void test_plxsd_0_R1 (void) { -+ __asm__ __volatile__ ("plxsd %0, +0(0), 1; pnop;pnop;pnop; " : "=v" (vrt) ); -+ PAD_ORI -+} -+static void test_plxssp_64_R1 (void) { -+ __asm__ __volatile__ ("plxssp %0, +64(0), 1; pnop;pnop;pnop; " : "=v" (vrt) ); -+ PAD_ORI -+ PAD_ORI -+} -+static void test_plxssp_32_R1 (void) { -+ __asm__ __volatile__ ("plxssp %0, +32(0), 1; pnop; " : "=v" (vrt) ); -+ PAD_ORI -+} -+static void test_plxssp_16_R1 (void) { -+ __asm__ __volatile__ ("plxssp %0, +16(0), 1; pnop;pnop;pnop; " : "=v" (vrt) ); -+ PAD_ORI -+} -+static void test_plxssp_8_R1 (void) { -+ __asm__ __volatile__ ("plxssp %0, +8(0), 1; pnop;pnop;pnop; " : "=v" (vrt) ); -+ PAD_ORI -+} -+static void test_plxssp_4_R1 (void) { -+ __asm__ __volatile__ ("plxssp %0, +4(0), 1; pnop;pnop;pnop; " : "=v" (vrt) ); -+ PAD_ORI -+} -+static void test_plxssp_0_R1 (void) { -+ __asm__ __volatile__ ("plxssp %0, +0(0), 1; pnop;pnop;pnop; " : "=v" (vrt) ); -+ PAD_ORI -+} -+/* Follow the short-range plxv instructions with nop in order to -+ pad out subsequent instructions. When written there are found -+ to be fluctuations in the instructions to store the result back -+ into the target variable. (pla,pstxv...). -+ */ -+static void test_plxv_16_R1 (void) { -+ __asm__ __volatile__ ("plxv %x0, +16(0), 1; pnop;pnop;pnop;" : "=wa" (vec_xt) ); -+ PAD_ORI -+} -+static void test_plxv_8_R1 (void) { -+ __asm__ __volatile__ ("plxv %x0, +8(0), 1; pnop;pnop;pnop;" : "=wa" (vec_xt) ); -+ PAD_ORI -+} -+static void test_plxv_4_R1 (void) { -+ __asm__ __volatile__ ("plxv %x0, +4(0), 1; pnop;pnop;pnop;" : "=wa" (vec_xt) ); -+ PAD_ORI -+} -+static void test_plxv_0_R1 (void) { -+ __asm__ __volatile__ ("plxv %x0, +0(0), 1; pnop;pnop;pnop; " : "=wa" (vec_xt) ); -+ PAD_ORI -+} -+static void test_pstxsd_64_R1 (void) { -+ __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+64(0), 1" ); -+} -+static void test_pstxsd_32_R1 (void) { -+ __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+32(0), 1" ); -+} -+static void test_pstxsd_16_R1 (void) { -+ __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+16(0), 1" ); -+} -+static void test_pstxsd_8_R1 (void) { -+ __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+8(0), 1" ); -+} -+static void test_pstxsd_4_R1 (void) { -+ __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+4(0), 1" ); -+} -+static void test_pstxsd_0_R1 (void) { -+ __asm__ __volatile__ (".align 2 ; pstxsd 22, -0x1f400+0(0), 1" ); -+} -+static void test_pstxssp_64_R1 (void) { -+ __asm__ __volatile__ ("pstxssp 22, -0x1f400+64(0), 1" ); -+} -+static void test_pstxssp_32_R1 (void) { -+ __asm__ __volatile__ ("pstxssp 22, -0x1f400+32(0), 1"); -+} -+static void test_pstxssp_16_R1 (void) { -+ __asm__ __volatile__ ("pstxssp 22, -0x1f400+16(0), 1"); -+} -+static void test_pstxssp_8_R1 (void) { -+ __asm__ __volatile__ ("pstxssp 22, -0x1f400+8(0), 1"); -+} -+static void test_pstxssp_4_R1 (void) { -+ __asm__ __volatile__ ("pstxssp 22, -0x1f400+4(0), 1"); -+} -+static void test_pstxssp_0_R1 (void) { -+ __asm__ __volatile__ ("pstxssp 22, -0x1f400+0(0), 1"); -+} -+static void test_pstxv_16_R1 (void) { -+ __asm__ __volatile__ ("pstxv %x0, -0x1f400+16(0), 1" :: "wa" (vec_xs)); -+} -+static void test_pstxv_8_R1 (void) { -+ __asm__ __volatile__ ("pstxv %x0, -0x1f400+8(0), 1" :: "wa" (vec_xs)); -+} -+static void test_pstxv_4_R1 (void) { -+ __asm__ __volatile__ ("pstxv %x0, -0x1f400+4(0), 1" :: "wa" (vec_xs)); -+} -+static void test_pstxv_0_R1 (void) { -+ __asm__ __volatile__ ("pstxv %x0, -0x1f400+0(0), 1" :: "wa" (vec_xs)); -+} -+ -+static test_list_t testgroup_generic[] = { -+ { &test_plfd_0_R1, "plfd 0_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfd_4_R1, "plfd 4_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfd_8_R1, "plfd 8_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfd_16_R1, "plfd 16_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfd_32_R1, "plfd 32_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfd_64_R1, "plfd 64_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfs_0_R1, "plfs 0_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfs_4_R1, "plfs 4_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfs_8_R1, "plfs 8_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfs_16_R1, "plfs 16_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfs_32_R1, "plfs 32_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plfs_64_R1, "plfs 64_R1", "FRT,D(RA),R"}, /* bcwp */ -+ { &test_plxsd_0_R1, "plxsd 0_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_plxsd_4_R1, "plxsd 4_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_plxsd_8_R1, "plxsd 8_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_plxsd_16_R1, "plxsd 16_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_plxsd_32_R1, "plxsd 32_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_plxsd_64_R1, "plxsd 64_R1", "VRT,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_plxssp_0_R1, "plxssp 0_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_plxssp_4_R1, "plxssp 4_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_plxssp_8_R1, "plxssp 8_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_plxssp_16_R1, "plxssp 16_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_plxssp_32_R1, "plxssp 32_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_plxssp_64_R1, "plxssp 64_R1", "VRT,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_plxv_0_R1, "plxv 0_R1", "XT,D(RA),R"}, /* bcwp */ -+ { &test_plxv_4_R1, "plxv 4_R1", "XT,D(RA),R"}, /* bcwp */ -+ { &test_plxv_8_R1, "plxv 8_R1", "XT,D(RA),R"}, /* bcwp */ -+ { &test_plxv_16_R1, "plxv 16_R1", "XT,D(RA),R"}, /* bcwp */ -+ { &test_pstfd_0_R1, "pstfd 0_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_pstfd_4_R1, "pstfd 4_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_pstfd_8_R1, "pstfd 8_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_pstfd_16_R1, "pstfd 16_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_pstfd_32_R1, "pstfd 32_R1", "FRS,D(RA),R", 0b00110000}, /* bcwp */ -+ { &test_pstfs_0_R1, "pstfs 0_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_pstfs_4_R1, "pstfs 4_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_pstfs_8_R1, "pstfs 8_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_pstfs_16_R1, "pstfs 16_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_pstfs_32_R1, "pstfs 32_R1", "FRS,D(RA),R", 0b00001111}, /* bcwp */ -+ { &test_pstxsd_0_R1, "pstxsd 0_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxsd_4_R1, "pstxsd 4_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxsd_8_R1, "pstxsd 8_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxsd_16_R1, "pstxsd 16_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxsd_32_R1, "pstxsd 32_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxsd_64_R1, "pstxsd 64_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxssp_0_R1, "pstxssp 0_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxssp_4_R1, "pstxssp 4_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxssp_8_R1, "pstxssp 8_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxssp_16_R1, "pstxssp 16_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxssp_32_R1, "pstxssp 32_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxssp_64_R1, "pstxssp 64_R1", "VRS,D(RA),R"}, /* bcwp */ -+ { &test_pstxvp_off0_R1, "pstxvp off0_R1", "XSp,D(RA),R"}, /* bcwp */ -+ { &test_pstxvp_off16_R1, "pstxvp off16_R1", "XSp,D(RA),R"}, /* bcwp */ -+ { &test_pstxvp_off32_R1, "pstxvp off32_R1", "XSp,D(RA),R"}, /* bcwp */ -+ { &test_pstxvp_off48_R1, "pstxvp off48_R1", "XSp,D(RA),R"}, /* bcwp */ -+ { &test_pstxv_0_R1, "pstxv 0_R1", "XS,D(RA),R"}, /* bcwp */ -+ { &test_pstxv_4_R1, "pstxv 4_R1", "XS,D(RA),R"}, /* bcwp */ -+ { &test_pstxv_8_R1, "pstxv 8_R1", "XS,D(RA),R"}, /* bcwp */ -+ { &test_pstxv_16_R1, "pstxv 16_R1", "XS,D(RA),R"}, /* bcwp */ -+ { NULL, NULL }, -+}; -+ -+/* Allow skipping of tests. */ -+unsigned long test_count=0xffff; -+unsigned long skip_count=0; -+unsigned long setup_only=0; -+ -+/* Set up a setjmp/longjmp to gently handle our SIGILLs and SIGSEGVs. */ -+static jmp_buf mybuf; -+ -+/* This (testfunction_generic) is meant to handle all of the instruction -+ variations. The helpers set up the register and iterator values -+ as is appropriate for the instruction being tested. */ -+static void testfunction_generic (const char* instruction_name, -+ test_func_t test_function, -+ unsigned int ignore_flags, -+ char * cur_form) { -+ -+ identify_form_components (instruction_name , cur_form); -+ debug_show_form (instruction_name, cur_form); -+ set_up_iterators (); -+ debug_show_iter_ranges (); -+ initialize_buffer (0); -+ init_pcrelative_write_target (); -+ debug_dump_buffer (); -+ -+ for (vrai = a_start; vrai < a_iters ; vrai+=a_inc) { -+ for (vrbi = b_start; vrbi < b_iters ; vrbi+=b_inc) { -+ for (vrci = c_start; vrci < c_iters ; vrci+=c_inc) { -+ for (vrmi = m_start; (vrmi < m_iters) ; vrmi+=m_inc) { -+ CHECK_OVERRIDES -+ debug_show_current_iteration (); -+ // Be sure to initialize the target registers first. -+ initialize_target_registers (); -+ initialize_source_registers (); -+ vec_xa[0]=0x1234; -+ vec_xa[1]=0x4567; -+ printf ("%s", instruction_name); -+ print_register_header (); -+ printf( " =>"); fflush (stdout); -+ if (!setup_only) { -+ if (enable_setjmp) { -+ if ( setjmp ( mybuf ) ) { -+ printf("signal tripped. (FIXME)\n"); -+ continue; -+ } -+ } -+ (*test_function) (); -+ } -+ print_register_footer (); -+ print_result_buffer (); -+ print_pcrelative_write_target (); -+ printf ("\n"); -+ } -+ } -+ } -+ } -+} -+ -+void mykillhandler ( int x ) { longjmp (mybuf, 1); } -+void mysegvhandler ( int x ) { longjmp (mybuf, 1); } -+ -+static void do_tests ( void ) -+{ -+ int groupcount; -+ char * cur_form; -+ test_group_t group_function = &testfunction_generic; -+ test_list_t *tests = testgroup_generic; -+ -+ struct sigaction kill_action, segv_action; -+ struct sigaction old_kill_action, old_segv_action; -+ if (enable_setjmp) { -+ kill_action.sa_handler = mykillhandler; -+ segv_action.sa_handler = mysegvhandler; -+ sigemptyset ( &kill_action.sa_mask ); -+ sigemptyset ( &segv_action.sa_mask ); -+ kill_action.sa_flags = SA_NODEFER; -+ segv_action.sa_flags = SA_NODEFER; -+ sigaction ( SIGILL, &kill_action, &old_kill_action); -+ sigaction ( SIGSEGV, &segv_action, &old_segv_action); -+ } -+ -+ for (groupcount = 0; tests[groupcount].name != NULL; groupcount++) { -+ cur_form = strdup(tests[groupcount].form); -+ current_test = tests[groupcount]; -+ identify_instruction_by_func_name (current_test.name); -+ if (groupcount < skip_count) continue; -+ if (verbose) printf("Test #%d ,", groupcount); -+ if (verbose > 1) printf(" instruction %s (v=%d)", current_test.name, verbose); -+ (*group_function) (current_test.name, current_test.func, 0, cur_form ); -+ printf ("\n"); -+ if (groupcount >= (skip_count+test_count)) break; -+ } -+ if (debug_show_labels) printf("\n"); -+ printf ("All done. Tested %d different instruction groups\n", groupcount); -+} -+ -+static void usage (void) -+{ -+ fprintf(stderr, -+ "Usage: test_isa_XXX [OPTIONS]\n" -+ "\t-h: display this help and exit\n" -+ "\t-v: increase verbosity\n" -+ "\t-a : limit number of a-iterations to \n" -+ "\t-b : limit number of b-iterations to \n" -+ "\t-c : limit number of c-iterations to \n" -+ "\t-n : limit to this number of tests.\n" -+ "\t-r : run only test # \n" -+ "\t\n" -+ "\t-j :enable setjmp to recover from illegal insns. \n" -+ "\t-m :(dev only?) lock VRM value to zero.\n" -+ "\t-z :(dev only?) lock MC value to zero.\n" -+ "\t-p :(dev only?) disable prefix instructions\n" -+ "\t-s : skip tests \n" -+ "\t-c : stop after running # of tests \n" -+ "\t-f : Do the test setup but do not actually execute the test instruction. \n" -+ ); -+} -+ -+int main (int argc, char **argv) -+{ -+ int c; -+ while ((c = getopt(argc, argv, "dhjvmpfzs:a:b:c:n:r:")) != -1) { -+ switch (c) { -+ case 'h': -+ usage(); -+ return 0; -+ -+ case 'v': -+ verbose++; -+ break; -+ -+ /* Options related to limiting the test iterations. */ -+ case 'a': -+ a_limit=atoi (optarg); -+ printf ("limiting a-iters to %ld.\n", a_limit); -+ break; -+ case 'b': -+ b_limit=atoi (optarg); -+ printf ("limiting b-iters to %ld.\n", b_limit); -+ break; -+ case 'c': -+ c_limit=atoi (optarg); -+ printf ("limiting c-iters to %ld.\n", c_limit); -+ break; -+ case 'n': // run this number of tests. -+ test_count=atoi (optarg); -+ printf ("limiting to %ld tests\n", test_count); -+ break; -+ case 'r': // run just test #. -+ skip_count=atoi (optarg); -+ test_count=0; -+ if (verbose) printf("Running test number %ld\n", skip_count); -+ break; -+ case 's': // skip this number of tests. -+ skip_count=atoi (optarg); -+ printf ("skipping %ld tests\n", skip_count); -+ break; -+ -+ /* debug options. */ -+ case 'd': -+ dump_tables=1; -+ printf("DEBUG:dump_tables.\n"); -+ break; -+ case 'f': -+ setup_only=1; -+ printf("DEBUG:setup_only.\n"); -+ break; -+ case 'j': -+ enable_setjmp=1; -+ printf ("DEBUG:setjmp enabled.\n"); -+ break; -+ case 'm': -+ vrm_override=1; -+ printf ("DEBUG:vrm override enabled.\n"); -+ break; -+ case 'p': -+ prefix_override=1; -+ printf ("DEBUG:prefix override enabled.\n"); -+ break; -+ case 'z': -+ mc_override=1; -+ printf ("DEBUG:MC override enabled.\n"); -+ break; -+ default: -+ usage(); -+ fprintf(stderr, "Unknown argument: '%c'\n", c); -+ } -+ } -+ -+ generic_prologue (); -+ build_vsx_table (); -+ build_args_table (); -+ build_float_vsx_tables (); -+ -+ if (dump_tables) { -+ dump_float_vsx_tables (); -+ dump_vsxargs (); -+ } -+ -+ do_tests (); -+ -+ return 0; -+} -+ -+#else // HAS_ISA_3_1 -+int main (int argc, char **argv) -+{ -+ printf("NO ISA 3.1 SUPPORT\n"); -+ return 0; -+} -+#endif -diff --git a/none/tests/ppc64/test_isa_3_1_R1_XT.stderr.exp b/none/tests/ppc64/test_isa_3_1_R1_XT.stderr.exp -new file mode 100644 -index 000000000..139597f9c ---- /dev/null -+++ b/none/tests/ppc64/test_isa_3_1_R1_XT.stderr.exp -@@ -0,0 +1,2 @@ -+ -+ -diff --git a/none/tests/ppc64/test_isa_3_1_R1_XT.stdout.exp b/none/tests/ppc64/test_isa_3_1_R1_XT.stdout.exp -new file mode 100644 -index 000000000..48d591f4d ---- /dev/null -+++ b/none/tests/ppc64/test_isa_3_1_R1_XT.stdout.exp -@@ -0,0 +1,127 @@ -+plfd 0_R1 =>_ -4.903986e+55 _ cb80000006100000, 0 -+ -+plfd 4_R1 =>_ 3.095878e+167 _ 62b50015cb800004, 0 -+ -+plfd 8_R1 =>_ 1.297320e+168 _ 62d6001662b50015, 0 -+ -+plfd 16_R1 =>_ 2.264413e+169 _ 6318001862f70017, 0 -+ -+plfd 32_R1 =>_ 6.763045e+171 _ 639c001c637b001b, 0 -+ -+plfd 64_R1 =>_ 6.763045e+171 _ 639c001c637b001b, 0 -+ -+plfs 0_R1 =>_ 2.708339e-35 _ 38c2000000000000, 0 -+ -+plfs 4_R1 =>_ -2.560001e+02 _ c070000080000000, 0 -+ -+plfs 8_R1 =>_ 1.669433e+21 _ 4456a002a0000000, 0 -+ -+plfs 16_R1 =>_ 2.278176e+21 _ 445ee002e0000000, 0 -+ -+plfs 32_R1 =>_ 4.630140e+21 _ 446f600360000000, 0 -+ -+plfs 64_R1 =>_ 4.630140e+21 _ 446f600360000000, 0 -+ -+plxsd 0_R1 => a800000004100000,0000000000000000 -5.07588375e-116 +Zero -+ -+plxsd 4_R1 => 7000000a8000004,0000000000000000 5.77662562e-275 +Zero -+ -+plxsd 8_R1 => 700000060000000,0000000000000000 5.77662407e-275 +Zero -+ -+plxsd 16_R1 => 7000000,0000000000000000 +Den +Zero -+ -+plxsd 32_R1 => 6339001963180018,0000000000000000 9.43505226e+169 +Zero -+ -+plxsd 64_R1 => 6339001963180018,0000000000000000 9.43505226e+169 +Zero -+ -+plxssp 0_R1 => 3882000000000000,0000000000000000 6.19888e-05 +Zero +Zero +Zero -+ -+plxssp 4_R1 => bd80000080000000,0000000000000000 -6.25000e-02 -Zero +Zero +Zero -+ -+plxssp 8_R1 => 38e0000000000000,0000000000000000 1.06812e-04 +Zero +Zero +Zero -+ -+plxssp 16_R1 => 38e0000000000000,0000000000000000 1.06812e-04 +Zero +Zero +Zero -+ -+plxssp 32_R1 => 445ac002c0000000,0000000000000000 8.75000e+02 -2.00000e+00 +Zero +Zero -+ -+plxssp 64_R1 => 446b400340000000,0000000000000000 9.41000e+02 2.00000e+00 +Zero +Zero -+ -+plxv 0_R1 => c800000004100000 7000000 -+ -+plxv 4_R1 => 7000000c8000004 700000000000000 -+ -+plxv 8_R1 => 7000000 7000000 -+ -+plxv 16_R1 => 7000000 7000000 -+ -+pstfd 0_R1 43dfe000003fe000 43eff000000ff000 => e000003fe00043df -+pstfd 0_R1 43eff000000ff000 43efefffffcff000 => f000000ff00043ef -+ -+pstfd 4_R1 43dfe000003fe000 43eff000000ff000 => e000003f e00043df -+pstfd 4_R1 43eff000000ff000 43efefffffcff000 => f000000f f00043ef -+ -+pstfd 8_R1 43dfe000003fe000 43eff000000ff000 => e000003fe00043df -+pstfd 8_R1 43eff000000ff000 43efefffffcff000 => f000000ff00043ef -+ -+pstfd 16_R1 43dfe000003fe000 43eff000000ff000 => e000003fe00043df -+pstfd 16_R1 43eff000000ff000 43efefffffcff000 => f000000ff00043ef -+ -+pstfd 32_R1 43dfe000003fe000 43eff000000ff000 => e000003fe00043df -+pstfd 32_R1 43eff000000ff000 43efefffffcff000 => f000000ff00043ef -+ -+pstfs 0_R1 000000005eff0000 000000005f7f8000 => 00005eff -+pstfs 0_R1 000000005f7f8000 000000005f7f8000 => 80005f7f -+ -+pstfs 4_R1 000000005eff0000 000000005f7f8000 => 00005eff -+pstfs 4_R1 000000005f7f8000 000000005f7f8000 => 80005f7f -+ -+pstfs 8_R1 000000005eff0000 000000005f7f8000 => 00005eff -+pstfs 8_R1 000000005f7f8000 000000005f7f8000 => 80005f7f -+ -+pstfs 16_R1 000000005eff0000 000000005f7f8000 => 00005eff -+pstfs 16_R1 000000005f7f8000 000000005f7f8000 => 80005f7f -+ -+pstfs 32_R1 000000005eff0000 000000005f7f8000 => 00005eff -+pstfs 32_R1 000000005f7f8000 000000005f7f8000 => 80005f7f -+ -+pstxsd 0_R1 => 0000000000000000 -+ -+pstxsd 4_R1 => 00000000 00000000 -+ -+pstxsd 8_R1 => 0000000000000000 -+ -+pstxsd 16_R1 => 0000000000000000 -+ -+pstxsd 32_R1 => 0000000000000000 -+ -+pstxsd 64_R1 => 0000000000000000 -+ -+pstxssp 0_R1 => 00000000 -+ -+pstxssp 4_R1 => 00000000 -+ -+pstxssp 8_R1 => 00000000 -+ -+pstxssp 16_R1 => 00000000 -+ -+pstxssp 32_R1 => 00000000 -+ -+pstxssp 64_R1 => 00000000 -+ -+pstxvp off0_R1 0180055e0180077e 0080000e8080000e ff7ffffe7f7ffffe ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 077e0180055e0180 000e8080000e0080 -+ -+pstxvp off16_R1 0180055e0180077e 0080000e8080000e ff7ffffe7f7ffffe ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 077e0180055e0180 000e8080000e0080 -+ -+pstxvp off32_R1 0180055e0180077e 0080000e8080000e ff7ffffe7f7ffffe ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 077e0180055e0180 000e8080000e0080 -+ -+pstxvp off48_R1 0180055e0180077e 0080000e8080000e ff7ffffe7f7ffffe ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 077e0180055e0180 000e8080000e0080 -+ -+pstxv 0_R1 ff7ffffe7f7ffffe,ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 -+ -+pstxv 4_R1 ff7ffffe7f7ffffe,ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 -+ -+pstxv 8_R1 ff7ffffe7f7ffffe,ff8000007f800000 => fffe7f7ffffeff7f 00007f800000ff80 -+ -+pstxv 16_R1 ff7ffffe7f7ffffe,ff8000007f800000 => fffe7f7f fffeff7f00007f80 0000ff80 -+ -+All done. Tested 58 different instruction groups -diff --git a/none/tests/ppc64/test_isa_3_1_R1_XT.vgtest b/none/tests/ppc64/test_isa_3_1_R1_XT.vgtest -new file mode 100644 -index 000000000..7331aafad ---- /dev/null -+++ b/none/tests/ppc64/test_isa_3_1_R1_XT.vgtest -@@ -0,0 +1,2 @@ -+prereq: ../../../tests/check_ppc64_auxv_cap arch_3_1 -+prog: test_isa_3_1_R1_XT -diff --git a/none/tests/ppc64/test_isa_3_1_common.c b/none/tests/ppc64/test_isa_3_1_common.c -index 7c3dc6f00..b3320277b 100644 ---- a/none/tests/ppc64/test_isa_3_1_common.c -+++ b/none/tests/ppc64/test_isa_3_1_common.c -@@ -134,11 +134,13 @@ bool uses_acc_vsrs; - bool uses_pmsk; - bool uses_buffer; // Buffer related. - bool uses_load_buffer, uses_store_buffer, uses_any_buffer; -+bool updates_byte, updates_halfword, updates_word; // output helpers. - bool uses_quad; - unsigned long output_mask; // Output field special handling. - bool instruction_is_sp, instruction_is_sp_estimate; - bool instruction_is_dp, instruction_is_dp_estimate; - bool instruction_is_b16; -+bool instruction_is_relative; - - unsigned long long min (unsigned long long a, unsigned long long b) { - if ( a < b ) -@@ -236,6 +238,18 @@ void identify_form_components (const char *instruction_name, - (strncmp (instruction_name, "pmst", 4) == 0) || - (strncmp (instruction_name, "pst", 3) == 0) || - (strncmp (instruction_name, "st", 2) == 0)); -+ updates_byte = ( -+ (strncmp (instruction_name, "pstb", 4) == 0) ); -+ updates_halfword = ( -+ (strncmp (instruction_name, "psth", 4) == 0) || -+ (strncmp (instruction_name, "pstfs", 4) == 0) || -+ (strncmp (instruction_name, "pstxsd", 4) == 0) || -+ (strncmp (instruction_name, "pstxssp", 4) == 0) || -+ (strncmp (instruction_name, "pstxv", 4) == 0) || -+ (strncmp (instruction_name, "psfs", 4) == 0) ); -+ updates_word = ( -+ (strncmp (instruction_name, "pstw", 4) == 0) ); -+ - uses_any_buffer = (strstr (cur_form, "(RA)") != NULL); - uses_buffer = uses_any_buffer||uses_load_buffer||uses_store_buffer; - -@@ -268,6 +282,15 @@ void identify_form_components (const char *instruction_name, - instruction_is_b16 = ( current_test.mask & B16_MASK ); - } - -+/* Parse the provided function name to set assorted values. -+ In particular, set an indicator when the instruction test has -+ indicated it will run with R==1 that indicates it is a PC-relative -+ instruction. Those tests should all have "_R1" as part of -+ the function name. */ -+void identify_instruction_by_func_name(const char * function_name) { -+ instruction_is_relative = ( (strstr (function_name, "R1") != NULL)); -+} -+ - void display_form_components (char * cur_form) { - printf (" %s\n", cur_form); - printf ("Instruction form elements: "); -@@ -288,7 +311,7 @@ void display_form_components (char * cur_form) { - if (has_frbp) printf ("frbp "); - if (has_frs) printf ("frs "); - if (has_frsp) printf ("frsp "); -- if (has_frt) printf ("frt "); -+ if (has_frt) printf ("frt%s ",(instruction_is_relative)?"-raw":""); - if (has_frtp) printf ("frtp "); - if (has_xa) printf ("xa "); - if (has_xap) printf ("xap "); -@@ -298,6 +321,7 @@ void display_form_components (char * cur_form) { - if (has_xsp) printf ("xsp "); - if (has_xt) printf ("xt "); - if (has_xtp) printf ("xtp "); -+ if (instruction_is_relative) printf ("R==1 "); - if (uses_acc_src) printf ("AS "); - if (uses_acc_dest) printf ("AT "); - printf ("\n"); -@@ -991,6 +1015,107 @@ if (debug_show_values) printf (" buffer:"); - } - } - -+/* **** Reloc Buffer **************************************** */ -+/* Create a large buffer to be the destination for pc-relative -+ * writes. This test is built with linker hints in order -+ * to ensure our buffer, stored in the .bss section, is at a -+ * mostly known offset from the instructions being exercised, -+ * so a hardcoded offset from the PC (pc-relative) will be -+ * on-target. -+ * If there are significant reworks to the code, the bss or -+ * text sections, or the offsets used may need to change. -+ * -+ * The linker hints are specifically -Tbss and -Ttext. -+ * gcc foo.c test_isa_3_1_common.c -I../../../ -Wl,-Tbss 0x20000 -Wl,-Ttext 0x40000 -+ */ -+ /* RELOC_BUFFER_SIZE is defined to 0x1000 in isa_3_1_helpers.h */ -+#define RELOC_BUFFER_PATTERN 0x0001000100010001 -+volatile unsigned long long pcrelative_write_target[RELOC_BUFFER_SIZE]; -+ -+/* Initialize the buffer to known values. */ -+void init_pcrelative_write_target() { -+ int i; -+ for (i=0;i %llx\n",i,ref_value,curr_value); -+ if (updates_byte) { -+ for (z=0;z<8;z++) { -+ rshift=z*8; -+ if (verbose) printf("z:%d ",z); -+ init_token = (ref_value>>rshift) & 0xff; -+ curr_token = (curr_value>>rshift) & 0xff; -+ if (verbose) -+ printf("wms byte:: %llx -> %llx \n",init_token,curr_token); -+ if (init_token == curr_token && (updates_byte||updates_halfword||updates_word) ) { -+ printf("%2s"," "); -+ } else { -+ printf("%02llx",curr_token); -+ } -+ } -+ } -+ else if (updates_halfword) { -+ for (z=0;z<4;z++) { -+ rshift=z*16; -+ if (verbose) printf("z:%d ",z); -+ init_token = (ref_value>>rshift) & 0xffff; -+ curr_token = (curr_value>>rshift) & 0xffff; -+ if (verbose) -+ printf("wms half:: %llx -> %llx \n",init_token,curr_token); -+ if (init_token == curr_token) { -+ printf("%2s"," "); -+ } else { -+ printf("%04llx",curr_token); -+ } -+ } -+ } -+ else if (updates_word) { -+ for (z=0;z<2;z++) { -+ rshift=z*32; -+ if (verbose) printf("z:%d ",z); -+ init_token = (ref_value>>rshift) & 0xffffffff; -+ curr_token = (curr_value>>rshift) & 0xffffffff; -+ if (verbose) -+ printf("wms word:: %llx -> %llx \n",init_token,curr_token); -+ if (init_token == curr_token ) { -+ printf("%2s"," "); -+ } else { -+ printf("%08llx",curr_token); -+ } -+ } -+ } -+ else { -+ printf("%016llx ",curr_value); -+ } -+ } -+ } -+} -+ -+/* Helper that returns the address of the pcrelative_write_target buffer. -+ Due to variances in where the sections land in memory, this value is -+ used to normalize the results. (see paddi tests for usage). */ -+unsigned long long pcrelative_buff_addr(int x) { -+ /* Return the base address of the array. The base address will be -+ a function of the code load address. */ -+ return (unsigned long long) &pcrelative_write_target[x]; -+} -+ - void print_undefined () { - if (debug_show_values) - printf (" [Undef]"); -@@ -1339,7 +1464,7 @@ void print_frt () { - /* If the result is a dfp128 value, the dfp128 value is - contained in the frt, frtp values which are split across - a pair of VSRs. */ -- if (uses_dfp128_output) { -+ if (!instruction_is_relative && uses_dfp128_output) { - if (verbose) print_vsr (28); - if (verbose) print_vsr (29); - value1 = get_vsrhd_vs28 (); -@@ -1347,7 +1472,12 @@ void print_frt () { - dissect_dfp128_float (value1, value3); - } else { - if (debug_show_raw_values) generic_print_float_as_hex (frt); -- printf (" %e", frt); -+ if (instruction_is_relative) { -+ printf ("_ %e _ ", frt); -+ print_vsr (28); -+ } else { -+ printf (" %e", frt); -+ } - if (has_frtp) { - if (debug_show_raw_values) generic_print_float_as_hex (frtp); - printf (" %e", frtp); -@@ -1652,7 +1782,15 @@ void print_all() { - void print_register_header () { - post_test = 0; - if (debug_show_all_regs) print_all(); -- if (has_ra) print_ra (); -+ -+ if (has_ra) { -+ /* Suppress the print of RA if the instruction has -+ R==1, since the ra value must be zero for the -+ instruction to be valid. */ -+ if (!instruction_is_relative) -+ print_ra(); -+ } -+ - if (has_rb) print_rb (); - if (has_rc) print_rc (); - if (has_rs) print_rs(); -@@ -1894,6 +2032,11 @@ void set_up_iterators () { - } else { - a_start=0; b_start=0; c_start=0; m_start=0; - } -+ /* Special casing for R==1 tests. */ -+ if (instruction_is_relative) { -+ a_iters = 1; -+ m_start=3; m_iters=4; -+ } - if ((has_vra+has_vrb+has_vrc+has_vrm+has_xa+has_xb+uses_MC > 2) && - (!debug_enable_all_iters)) { - /* Instruction tests using multiple fields will generate a lot of -@@ -2196,15 +2339,12 @@ void initialize_source_registers () { - vrb[0] = vsxargs[ (vrbi ) % isr_modulo]; - vrb[1] = vsxargs[ (vrbi+1) % isr_modulo]; - } -- -- if (has_xa) { -- vec_xa[0] = vsxargs[ (vrai ) % isr_modulo]; -- vec_xa[1] = vsxargs[ (vrai+1) % isr_modulo]; -- } -- if (has_xb) { -- vec_xb[0] = vsxargs[ (vrbi ) % isr_modulo]; -- vec_xb[1] = vsxargs[ (vrbi+1) % isr_modulo]; -- } -+ -+ if (instruction_is_relative) { -+ /* for pstxsd and friends using R=1 */ -+ vec_xa[0] = vsxargs[ (vrai+2 ) % isr_modulo]; -+ vec_xa[1] = vsxargs[ (vrai+3 ) % isr_modulo]; -+ } - - // xap 'shares' with the second half of an xa-pair. - if (has_xap ) { diff --git a/SOURCES/valgrind-3.18.1-ppc-pstq.patch b/SOURCES/valgrind-3.18.1-ppc-pstq.patch deleted file mode 100644 index 2e23d18..0000000 --- a/SOURCES/valgrind-3.18.1-ppc-pstq.patch +++ /dev/null @@ -1,47 +0,0 @@ -commit ae8c6de01417023e78763de145b1c0e6ddd87277 -Author: Carl Love -Date: Wed Oct 20 20:40:13 2021 +0000 - - Fix for the prefixed stq instruction in PC relative mode. - - The pstq instruction for R=1, was not using the correct effective address. - The EA_hi and EA_lo should have been based on the value of EA as calculated - by the function calculate_prefix_EA. Unfortuanely, the EA_hi and EA_lo - addresses were still using the previous code (not PC relative) to calculate - the address from the contants of RA plus the offset. - -diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c -index 8afd77490..543fa9574 100644 ---- a/VEX/priv/guest_ppc_toIR.c -+++ b/VEX/priv/guest_ppc_toIR.c -@@ -9838,23 +9838,24 @@ static Bool dis_int_store_ds_prefix ( UInt prefix, - if (host_endness == VexEndnessBE) { - - /* upper 64-bits */ -- assign( EA_hi, ea_rAor0_simm( rA_addr, immediate_val ) ); -+ assign( EA_hi, mkexpr(EA)); - - /* lower 64-bits */ -- assign( EA_lo, ea_rAor0_simm( rA_addr, immediate_val+8 ) ); -+ assign( EA_lo, binop(Iop_Add64, mkexpr(EA), mkU64(8))); -+ - } else { - /* upper 64-bits */ -- assign( EA_hi, ea_rAor0_simm( rA_addr, immediate_val+8 ) ); -+ assign( EA_hi, binop(Iop_Add64, mkexpr(EA), mkU64(8))); - - /* lower 64-bits */ -- assign( EA_lo, ea_rAor0_simm( rA_addr, immediate_val ) ); -+ assign( EA_lo, mkexpr(EA)); - } - } else { - /* upper half of upper 64-bits */ -- assign( EA_hi, ea_rAor0_simm( rA_addr, immediate_val+4 ) ); -+ assign( EA_hi, binop(Iop_Add32, mkexpr(EA), mkU32(4))); - - /* lower half of upper 64-bits */ -- assign( EA_lo, ea_rAor0_simm( rA_addr, immediate_val+12 ) ); -+ assign( EA_lo, binop(Iop_Add32, mkexpr(EA), mkU32(12))); - } - - /* Note, the store order for stq instruction is the same for BE diff --git a/SOURCES/valgrind-3.18.1-ppc64-lxsibzx-lxsihzx.patch b/SOURCES/valgrind-3.18.1-ppc64-lxsibzx-lxsihzx.patch deleted file mode 100644 index bb36c80..0000000 --- a/SOURCES/valgrind-3.18.1-ppc64-lxsibzx-lxsihzx.patch +++ /dev/null @@ -1,60 +0,0 @@ -commit 6e08ee95f7f1b1c3fd434fa380cc5b2cc3e3f7c7 -Author: Carl Love -Date: Fri Oct 29 16:30:33 2021 -0500 - - Bug 444571 - PPC, fix the lxsibzx and lxsihzx so they only load their respective sized data. - - The lxsibzx was doing a 64-bit load. The result was initializing - additional bytes in the register that should not have been initialized. - The memcheck/tests/linux/dlclose_leak test detected the issue. The - code generation uses lxsibzx and stxsibx with -mcpu=power9. Previously - the lbz and stb instructions were generated. - - The same issue was noted and fixed with the lxsihzx instruction. The - memcheck/tests/linux/badrw test now passes as well. - - https://bugs.kde.org/show_bug.cgi?id=444571 - -diff --git a/VEX/priv/guest_ppc_toIR.c b/VEX/priv/guest_ppc_toIR.c -index d90d566ed..8afd77490 100644 ---- a/VEX/priv/guest_ppc_toIR.c -+++ b/VEX/priv/guest_ppc_toIR.c -@@ -25359,19 +25359,17 @@ dis_vx_load ( UInt prefix, UInt theInstr ) - - else - irx_addr = mkexpr( EA ); -- -- byte = load( Ity_I64, irx_addr ); -+ /* byte load */ -+ byte = load( Ity_I8, irx_addr ); - putVSReg( XT, binop( Iop_64HLtoV128, -- binop( Iop_And64, -- byte, -- mkU64( 0xFF ) ), -+ unop( Iop_8Uto64, byte ), - mkU64( 0 ) ) ); - break; - } - - case 0x32D: // lxsihzx - { -- IRExpr *byte; -+ IRExpr *hword; - IRExpr* irx_addr; - - DIP("lxsihzx %u,r%u,r%u\n", (UInt)XT, rA_addr, rB_addr); -@@ -25382,11 +25380,10 @@ dis_vx_load ( UInt prefix, UInt theInstr ) - else - irx_addr = mkexpr( EA ); - -- byte = load( Ity_I64, irx_addr ); -+ hword = load( Ity_I16, irx_addr ); - putVSReg( XT, binop( Iop_64HLtoV128, -- binop( Iop_And64, -- byte, -- mkU64( 0xFFFF ) ), -+ unop( Iop_16Uto64, -+ hword ), - mkU64( 0 ) ) ); - break; - } diff --git a/SOURCES/valgrind-3.18.1-rust-v0-demangle.patch b/SOURCES/valgrind-3.18.1-rust-v0-demangle.patch deleted file mode 100644 index e48a106..0000000 --- a/SOURCES/valgrind-3.18.1-rust-v0-demangle.patch +++ /dev/null @@ -1,137 +0,0 @@ -commit 4831385c6706b377851284adc4c4545fff4c6564 -Author: Nicholas Nethercote -Date: Tue Nov 9 12:30:07 2021 +1100 - - Fix Rust v0 demangling. - - It's currently broken due to a silly test that prevents the v0 - demangling code from even running. - - The commit also adds a test, to avoid such problems in the future. - -diff --git a/coregrind/m_demangle/demangle.c b/coregrind/m_demangle/demangle.c -index 16161da2a..3fd7cb75f 100644 ---- a/coregrind/m_demangle/demangle.c -+++ b/coregrind/m_demangle/demangle.c -@@ -118,8 +118,13 @@ void VG_(demangle) ( Bool do_cxx_demangling, Bool do_z_demangling, - } - - /* Possibly undo (1) */ -+ // - C++ mangled symbols start with "_Z" (possibly with exceptions?) -+ // - Rust "legacy" mangled symbols start with "_Z". -+ // - Rust "v0" mangled symbols start with "_R". -+ // XXX: the Java/Rust/Ada demangling here probably doesn't work. See -+ // https://bugs.kde.org/show_bug.cgi?id=445235 for details. - if (do_cxx_demangling && VG_(clo_demangle) -- && orig != NULL && orig[0] == '_' && orig[1] == 'Z') { -+ && orig != NULL && orig[0] == '_' && (orig[1] == 'Z' || orig[1] == 'R')) { - /* !!! vvv STATIC vvv !!! */ - static HChar* demangled = NULL; - /* !!! ^^^ STATIC ^^^ !!! */ -diff --git a/memcheck/tests/demangle-rust.c b/memcheck/tests/demangle-rust.c -new file mode 100644 -index 000000000..f2a458b2a ---- /dev/null -+++ b/memcheck/tests/demangle-rust.c -@@ -0,0 +1,31 @@ -+// Valgrind supports demangling Rust symbols (both the "v0" and "legacy" -+// mangling schemes), but we don't want to add a dependency on the Rust -+// compiler for a single test. So this is a C program with function names that -+// are mangled Rust symbols. In the output, they become demangled Rust names. -+// It's a hack, but a useful one. -+ -+#include -+ -+// A v0 symbol that demangles to: ::fold_with:: -+int _RINvYNtNtCs4uGc65yWeeX_12rustc_middle2ty13PredicateKindNtNtB5_4fold12TypeFoldable9fold_withNtNtNtCsgI90OQiJWEs_11rustc_infer5infer7resolve24OpportunisticVarResolverECsdozMG8X9FIu_21rustc_trait_selection(int *p) -+{ -+ return *p ? 1 : 2; -+} -+ -+// A v0 symbol that demangles to: rustc_expand::mbe::macro_parser::parse_tt -+int _RNvNtNtCsaqSe1lZGvEL_12rustc_expand3mbe12macro_parser8parse_tt(int* p) -+{ -+ return _RINvYNtNtCs4uGc65yWeeX_12rustc_middle2ty13PredicateKindNtNtB5_4fold12TypeFoldable9fold_withNtNtNtCsgI90OQiJWEs_11rustc_infer5infer7resolve24OpportunisticVarResolverECsdozMG8X9FIu_21rustc_trait_selection(p); -+} -+ -+// A legacy symbol that demangles to: core::str::lossy::Utf8Lossy::from_bytes -+int _ZN4core3str5lossy9Utf8Lossy10from_bytes17heb1677c8cb728b0bE(int* p) -+{ -+ return _RNvNtNtCsaqSe1lZGvEL_12rustc_expand3mbe12macro_parser8parse_tt(p); -+} -+ -+int main(void) -+{ -+ return _ZN4core3str5lossy9Utf8Lossy10from_bytes17heb1677c8cb728b0bE(malloc(sizeof(int))); -+} -+ -diff --git a/memcheck/tests/demangle-rust.stderr.exp b/memcheck/tests/demangle-rust.stderr.exp -new file mode 100644 -index 000000000..f04bb625b ---- /dev/null -+++ b/memcheck/tests/demangle-rust.stderr.exp -@@ -0,0 +1,6 @@ -+Conditional jump or move depends on uninitialised value(s) -+ at 0x........: ::fold_with:: (demangle-rust.c:12) -+ by 0x........: rustc_expand::mbe::macro_parser::parse_tt (demangle-rust.c:18) -+ by 0x........: core::str::lossy::Utf8Lossy::from_bytes (demangle-rust.c:24) -+ by 0x........: main (demangle-rust.c:29) -+ -diff --git a/memcheck/tests/demangle-rust.vgtest b/memcheck/tests/demangle-rust.vgtest -new file mode 100644 -index 000000000..d726c6b2e ---- /dev/null -+++ b/memcheck/tests/demangle-rust.vgtest -@@ -0,0 +1,2 @@ -+prog: demangle-rust -+vgopts: -q - -commit c1bfa115f985633722f25922d2996c231e8c9d8d -Author: Mark Wielaard -Date: Wed Nov 10 09:02:36 2021 +0100 - - Add demangle-rust.vgtest demangle-rust.stderr.exp to EXTRA_DIST - -diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am -index 4d0476e2d..7837d87c7 100644 ---- a/memcheck/tests/Makefile.am -+++ b/memcheck/tests/Makefile.am -@@ -281,6 +281,7 @@ EXTRA_DIST = \ - realloc3.stderr.exp realloc3.vgtest \ - recursive-merge.stderr.exp recursive-merge.vgtest \ - resvn_stack.stderr.exp resvn_stack.vgtest \ -+ demangle-rust.vgtest demangle-rust.stderr.exp \ - sbfragment.stdout.exp sbfragment.stderr.exp sbfragment.vgtest \ - sem.stderr.exp sem.vgtest \ - sendmsg.stderr.exp sendmsg.stderr.exp-solaris sendmsg.vgtest \ - -commit d151907e5d8ff393f4fef126c8ae445ea8813661 -Author: Mark Wielaard -Date: Thu Nov 11 18:02:09 2021 +0100 - - Add demangle-rust to check_PROGRAMS - - The demangle-rust.vgtest would fail because the demangle-rust binary - wasn't build by default. Add it to check_PROGRAMS and define - demangle_rust_SOURCES to make sure it is always build. - -diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am -index 7837d87c7..449710020 100644 ---- a/memcheck/tests/Makefile.am -+++ b/memcheck/tests/Makefile.am -@@ -392,6 +392,7 @@ check_PROGRAMS = \ - custom_alloc \ - custom-overlap \ - demangle \ -+ demangle-rust \ - big_debuginfo_symbol \ - deep-backtrace \ - describe-block \ -@@ -505,6 +506,7 @@ endif - leak_cpp_interior_SOURCES = leak_cpp_interior.cpp - - demangle_SOURCES = demangle.cpp -+demangle_rust_SOURCES = demangle-rust.c - - # Suppress various gcc warnings which are correct, but for things - # we are actually testing for at runtime. diff --git a/SOURCES/valgrind-3.18.1-s390x-EXRL.patch b/SOURCES/valgrind-3.18.1-s390x-EXRL.patch deleted file mode 100644 index 6927cc3..0000000 --- a/SOURCES/valgrind-3.18.1-s390x-EXRL.patch +++ /dev/null @@ -1,549 +0,0 @@ -commit b77dbefe72e4a5c7bcf1576a02c909010bd56991 -Author: Andreas Arnez -Date: Fri Oct 22 19:55:12 2021 +0200 - - Bug 444242 - s390x: Sign-extend "relative long" offset in EXRL - - In s390_irgen_EXRL, the offset is zero-extended instead of sign-extended, - typically causing Valgrind to crash when a negative offset occurs. - - Fix this with a new helper function that calculates a "relative long" - address from a 32-bit offset. Replace other calculations of "relative - long" addresses by invocations of this function as well. And for - consistency, do the same with "relative" (short) addresses. - -diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c -index 72222ab04..fffc563d4 100644 ---- a/VEX/priv/guest_s390_toIR.c -+++ b/VEX/priv/guest_s390_toIR.c -@@ -399,6 +399,22 @@ mkF64i(ULong value) - return IRExpr_Const(IRConst_F64i(value)); - } - -+/* Return the 64-bit address with the given 32-bit "relative long" offset from -+ the current guest instruction being translated. */ -+static __inline__ Addr64 -+addr_rel_long(UInt offset) -+{ -+ return guest_IA_curr_instr + ((Addr64)(Long)(Int)offset << 1); -+} -+ -+/* Return the 64-bit address with the given 16-bit "relative" offset from the -+ current guest instruction being translated. */ -+static __inline__ Addr64 -+addr_relative(UShort offset) -+{ -+ return guest_IA_curr_instr + ((Addr64)(Long)(Short)offset << 1); -+} -+ - /* Little helper function for my sanity. ITE = if-then-else */ - static IRExpr * - mkite(IRExpr *condition, IRExpr *iftrue, IRExpr *iffalse) -@@ -5516,7 +5532,7 @@ static const HChar * - s390_irgen_BRAS(UChar r1, UShort i2) - { - put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 4ULL)); -- call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); -+ call_function_and_chase(addr_relative(i2)); - - return "bras"; - } -@@ -5525,7 +5541,7 @@ static const HChar * - s390_irgen_BRASL(UChar r1, UInt i2) - { - put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + 6ULL)); -- call_function_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)); -+ call_function_and_chase(addr_rel_long(i2)); - - return "brasl"; - } -@@ -5538,12 +5554,11 @@ s390_irgen_BRC(UChar r1, UShort i2) - if (r1 == 0) { - } else { - if (r1 == 15) { -- always_goto_and_chase( -- guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); -+ always_goto_and_chase(addr_relative(i2)); - } else { - assign(cond, s390_call_calculate_cond(r1)); - if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); -+ addr_relative(i2)); - - } - } -@@ -5561,11 +5576,11 @@ s390_irgen_BRCL(UChar r1, UInt i2) - if (r1 == 0) { - } else { - if (r1 == 15) { -- always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)); -+ always_goto_and_chase(addr_rel_long(i2)); - } else { - assign(cond, s390_call_calculate_cond(r1)); - if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)); -+ addr_rel_long(i2)); - } - } - if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) -@@ -5579,7 +5594,7 @@ s390_irgen_BRCT(UChar r1, UShort i2) - { - put_gpr_w1(r1, binop(Iop_Sub32, get_gpr_w1(r1), mkU32(1))); - if_condition_goto(binop(Iop_CmpNE32, get_gpr_w1(r1), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); -+ addr_relative(i2)); - - return "brct"; - } -@@ -5589,7 +5604,7 @@ s390_irgen_BRCTH(UChar r1, UInt i2) - { - put_gpr_w0(r1, binop(Iop_Sub32, get_gpr_w0(r1), mkU32(1))); - if_condition_goto(binop(Iop_CmpNE32, get_gpr_w0(r1), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); -+ addr_relative(i2)); - - return "brcth"; - } -@@ -5599,7 +5614,7 @@ s390_irgen_BRCTG(UChar r1, UShort i2) - { - put_gpr_dw0(r1, binop(Iop_Sub64, get_gpr_dw0(r1), mkU64(1))); - if_condition_goto(binop(Iop_CmpNE64, get_gpr_dw0(r1), mkU64(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); -+ addr_relative(i2)); - - return "brctg"; - } -@@ -5612,7 +5627,7 @@ s390_irgen_BRXH(UChar r1, UChar r3, UShort i2) - assign(value, get_gpr_w1(r3 | 1)); - put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3))); - if_condition_goto(binop(Iop_CmpLT32S, mkexpr(value), get_gpr_w1(r1)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); -+ addr_relative(i2)); - - return "brxh"; - } -@@ -5625,7 +5640,7 @@ s390_irgen_BRXHG(UChar r1, UChar r3, UShort i2) - assign(value, get_gpr_dw0(r3 | 1)); - put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3))); - if_condition_goto(binop(Iop_CmpLT64S, mkexpr(value), get_gpr_dw0(r1)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); -+ addr_relative(i2)); - - return "brxhg"; - } -@@ -5638,7 +5653,7 @@ s390_irgen_BRXLE(UChar r1, UChar r3, UShort i2) - assign(value, get_gpr_w1(r3 | 1)); - put_gpr_w1(r1, binop(Iop_Add32, get_gpr_w1(r1), get_gpr_w1(r3))); - if_condition_goto(binop(Iop_CmpLE32S, get_gpr_w1(r1), mkexpr(value)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); -+ addr_relative(i2)); - - return "brxle"; - } -@@ -5651,7 +5666,7 @@ s390_irgen_BRXLG(UChar r1, UChar r3, UShort i2) - assign(value, get_gpr_dw0(r3 | 1)); - put_gpr_dw0(r1, binop(Iop_Add64, get_gpr_dw0(r1), get_gpr_dw0(r3))); - if_condition_goto(binop(Iop_CmpLE64S, get_gpr_dw0(r1), mkexpr(value)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i2 << 1)); -+ addr_relative(i2)); - - return "brxlg"; - } -@@ -5782,8 +5797,7 @@ s390_irgen_CRL(UChar r1, UInt i2) - IRTemp op2 = newTemp(Ity_I32); - - assign(op1, get_gpr_w1(r1)); -- assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) -- i2 << 1)))); -+ assign(op2, load(Ity_I32, mkU64(addr_rel_long(i2)))); - s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "crl"; -@@ -5796,8 +5810,7 @@ s390_irgen_CGRL(UChar r1, UInt i2) - IRTemp op2 = newTemp(Ity_I64); - - assign(op1, get_gpr_dw0(r1)); -- assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) -- i2 << 1)))); -+ assign(op2, load(Ity_I64, mkU64(addr_rel_long(i2)))); - s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cgrl"; -@@ -5810,8 +5823,7 @@ s390_irgen_CGFRL(UChar r1, UInt i2) - IRTemp op2 = newTemp(Ity_I64); - - assign(op1, get_gpr_dw0(r1)); -- assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ assign(op2, unop(Iop_32Sto64, load(Ity_I32, mkU64(addr_rel_long(i2))))); - s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cgfrl"; -@@ -5875,15 +5887,14 @@ s390_irgen_CRJ(UChar r1, UChar r2, UShort i4, UChar m3) - if (m3 == 0) { - } else { - if (m3 == 14) { -- always_goto_and_chase( -- guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ always_goto_and_chase(addr_relative(i4)); - } else { - assign(op1, get_gpr_w1(r1)); - assign(op2, get_gpr_w1(r2)); - assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, - op1, op2)); - if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ addr_relative(i4)); - - } - } -@@ -5901,15 +5912,14 @@ s390_irgen_CGRJ(UChar r1, UChar r2, UShort i4, UChar m3) - if (m3 == 0) { - } else { - if (m3 == 14) { -- always_goto_and_chase( -- guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ always_goto_and_chase(addr_relative(i4)); - } else { - assign(op1, get_gpr_dw0(r1)); - assign(op2, get_gpr_dw0(r2)); - assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, - op1, op2)); - if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ addr_relative(i4)); - - } - } -@@ -5975,14 +5985,14 @@ s390_irgen_CIJ(UChar r1, UChar m3, UShort i4, UChar i2) - if (m3 == 0) { - } else { - if (m3 == 14) { -- always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ always_goto_and_chase(addr_relative(i4)); - } else { - assign(op1, get_gpr_w1(r1)); - op2 = (Int)(Char)i2; - assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1, - mktemp(Ity_I32, mkU32((UInt)op2)))); - if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ addr_relative(i4)); - - } - } -@@ -6000,14 +6010,14 @@ s390_irgen_CGIJ(UChar r1, UChar m3, UShort i4, UChar i2) - if (m3 == 0) { - } else { - if (m3 == 14) { -- always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ always_goto_and_chase(addr_relative(i4)); - } else { - assign(op1, get_gpr_dw0(r1)); - op2 = (Long)(Char)i2; - assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_SIGNED_COMPARE, op1, - mktemp(Ity_I64, mkU64((ULong)op2)))); - if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ addr_relative(i4)); - - } - } -@@ -6131,8 +6141,7 @@ s390_irgen_CHRL(UChar r1, UInt i2) - IRTemp op2 = newTemp(Ity_I32); - - assign(op1, get_gpr_w1(r1)); -- assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ assign(op2, unop(Iop_16Sto32, load(Ity_I16, mkU64(addr_rel_long(i2))))); - s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "chrl"; -@@ -6145,8 +6154,7 @@ s390_irgen_CGHRL(UChar r1, UInt i2) - IRTemp op2 = newTemp(Ity_I64); - - assign(op1, get_gpr_dw0(r1)); -- assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ assign(op2, unop(Iop_16Sto64, load(Ity_I16, mkU64(addr_rel_long(i2))))); - s390_cc_thunk_putSS(S390_CC_OP_SIGNED_COMPARE, op1, op2); - - return "cghrl"; -@@ -6401,8 +6409,7 @@ s390_irgen_CLRL(UChar r1, UInt i2) - IRTemp op2 = newTemp(Ity_I32); - - assign(op1, get_gpr_w1(r1)); -- assign(op2, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) -- i2 << 1)))); -+ assign(op2, load(Ity_I32, mkU64(addr_rel_long(i2)))); - s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clrl"; -@@ -6415,8 +6422,7 @@ s390_irgen_CLGRL(UChar r1, UInt i2) - IRTemp op2 = newTemp(Ity_I64); - - assign(op1, get_gpr_dw0(r1)); -- assign(op2, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) -- i2 << 1)))); -+ assign(op2, load(Ity_I64, mkU64(addr_rel_long(i2)))); - s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clgrl"; -@@ -6429,8 +6435,7 @@ s390_irgen_CLGFRL(UChar r1, UInt i2) - IRTemp op2 = newTemp(Ity_I64); - - assign(op1, get_gpr_dw0(r1)); -- assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ assign(op2, unop(Iop_32Uto64, load(Ity_I32, mkU64(addr_rel_long(i2))))); - s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clgfrl"; -@@ -6443,8 +6448,7 @@ s390_irgen_CLHRL(UChar r1, UInt i2) - IRTemp op2 = newTemp(Ity_I32); - - assign(op1, get_gpr_w1(r1)); -- assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ assign(op2, unop(Iop_16Uto32, load(Ity_I16, mkU64(addr_rel_long(i2))))); - s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clhrl"; -@@ -6457,8 +6461,7 @@ s390_irgen_CLGHRL(UChar r1, UInt i2) - IRTemp op2 = newTemp(Ity_I64); - - assign(op1, get_gpr_dw0(r1)); -- assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ assign(op2, unop(Iop_16Uto64, load(Ity_I16, mkU64(addr_rel_long(i2))))); - s390_cc_thunk_putZZ(S390_CC_OP_UNSIGNED_COMPARE, op1, op2); - - return "clghrl"; -@@ -6730,14 +6733,14 @@ s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3) - if (m3 == 0) { - } else { - if (m3 == 14) { -- always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ always_goto_and_chase(addr_relative(i4)); - } else { - assign(op1, get_gpr_w1(r1)); - assign(op2, get_gpr_w1(r2)); - assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, - op1, op2)); - if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ addr_relative(i4)); - - } - } -@@ -6755,14 +6758,14 @@ s390_irgen_CLGRJ(UChar r1, UChar r2, UShort i4, UChar m3) - if (m3 == 0) { - } else { - if (m3 == 14) { -- always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ always_goto_and_chase(addr_relative(i4)); - } else { - assign(op1, get_gpr_dw0(r1)); - assign(op2, get_gpr_dw0(r2)); - assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, - op1, op2)); - if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ addr_relative(i4)); - - } - } -@@ -6828,14 +6831,14 @@ s390_irgen_CLIJ(UChar r1, UChar m3, UShort i4, UChar i2) - if (m3 == 0) { - } else { - if (m3 == 14) { -- always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ always_goto_and_chase(addr_relative(i4)); - } else { - assign(op1, get_gpr_w1(r1)); - op2 = (UInt)i2; - assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1, - mktemp(Ity_I32, mkU32(op2)))); - if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ addr_relative(i4)); - - } - } -@@ -6853,14 +6856,14 @@ s390_irgen_CLGIJ(UChar r1, UChar m3, UShort i4, UChar i2) - if (m3 == 0) { - } else { - if (m3 == 14) { -- always_goto_and_chase(guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ always_goto_and_chase(addr_relative(i4)); - } else { - assign(op1, get_gpr_dw0(r1)); - op2 = (ULong)i2; - assign(cond, s390_call_calculate_icc(m3, S390_CC_OP_UNSIGNED_COMPARE, op1, - mktemp(Ity_I64, mkU64(op2)))); - if_condition_goto(binop(Iop_CmpNE32, mkexpr(cond), mkU32(0)), -- guest_IA_curr_instr + ((ULong)(Long)(Short)i4 << 1)); -+ addr_relative(i4)); - - } - } -@@ -7539,8 +7542,7 @@ s390_irgen_LGFI(UChar r1, UInt i2) - static const HChar * - s390_irgen_LRL(UChar r1, UInt i2) - { -- put_gpr_w1(r1, load(Ity_I32, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) -- i2 << 1)))); -+ put_gpr_w1(r1, load(Ity_I32, mkU64(addr_rel_long(i2)))); - - return "lrl"; - } -@@ -7548,8 +7550,7 @@ s390_irgen_LRL(UChar r1, UInt i2) - static const HChar * - s390_irgen_LGRL(UChar r1, UInt i2) - { -- put_gpr_dw0(r1, load(Ity_I64, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int) -- i2 << 1)))); -+ put_gpr_dw0(r1, load(Ity_I64, mkU64(addr_rel_long(i2)))); - - return "lgrl"; - } -@@ -7557,8 +7558,7 @@ s390_irgen_LGRL(UChar r1, UInt i2) - static const HChar * - s390_irgen_LGFRL(UChar r1, UInt i2) - { -- put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ put_gpr_dw0(r1, unop(Iop_32Sto64, load(Ity_I32, mkU64(addr_rel_long(i2))))); - - return "lgfrl"; - } -@@ -7598,7 +7598,7 @@ s390_irgen_LAEY(UChar r1, IRTemp op2addr) - static const HChar * - s390_irgen_LARL(UChar r1, UInt i2) - { -- put_gpr_dw0(r1, mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1))); -+ put_gpr_dw0(r1, mkU64(addr_rel_long(i2))); - - return "larl"; - } -@@ -8038,8 +8038,7 @@ s390_irgen_LGHI(UChar r1, UShort i2) - static const HChar * - s390_irgen_LHRL(UChar r1, UInt i2) - { -- put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ put_gpr_w1(r1, unop(Iop_16Sto32, load(Ity_I16, mkU64(addr_rel_long(i2))))); - - return "lhrl"; - } -@@ -8047,8 +8046,7 @@ s390_irgen_LHRL(UChar r1, UInt i2) - static const HChar * - s390_irgen_LGHRL(UChar r1, UInt i2) - { -- put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ put_gpr_dw0(r1, unop(Iop_16Sto64, load(Ity_I16, mkU64(addr_rel_long(i2))))); - - return "lghrl"; - } -@@ -8088,8 +8086,7 @@ s390_irgen_LLGF(UChar r1, IRTemp op2addr) - static const HChar * - s390_irgen_LLGFRL(UChar r1, UInt i2) - { -- put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ put_gpr_dw0(r1, unop(Iop_32Uto64, load(Ity_I32, mkU64(addr_rel_long(i2))))); - - return "llgfrl"; - } -@@ -8169,8 +8166,7 @@ s390_irgen_LLGH(UChar r1, IRTemp op2addr) - static const HChar * - s390_irgen_LLHRL(UChar r1, UInt i2) - { -- put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ put_gpr_w1(r1, unop(Iop_16Uto32, load(Ity_I16, mkU64(addr_rel_long(i2))))); - - return "llhrl"; - } -@@ -8178,8 +8174,7 @@ s390_irgen_LLHRL(UChar r1, UInt i2) - static const HChar * - s390_irgen_LLGHRL(UChar r1, UInt i2) - { -- put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(guest_IA_curr_instr + -- ((ULong)(Long)(Int)i2 << 1))))); -+ put_gpr_dw0(r1, unop(Iop_16Uto64, load(Ity_I16, mkU64(addr_rel_long(i2))))); - - return "llghrl"; - } -@@ -10064,8 +10059,7 @@ s390_irgen_STG(UChar r1, IRTemp op2addr) - static const HChar * - s390_irgen_STRL(UChar r1, UInt i2) - { -- store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)), -- get_gpr_w1(r1)); -+ store(mkU64(addr_rel_long(i2)), get_gpr_w1(r1)); - - return "strl"; - } -@@ -10073,8 +10067,7 @@ s390_irgen_STRL(UChar r1, UInt i2) - static const HChar * - s390_irgen_STGRL(UChar r1, UInt i2) - { -- store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)), -- get_gpr_dw0(r1)); -+ store(mkU64(addr_rel_long(i2)), get_gpr_dw0(r1)); - - return "stgrl"; - } -@@ -10203,8 +10196,7 @@ s390_irgen_STHY(UChar r1, IRTemp op2addr) - static const HChar * - s390_irgen_STHRL(UChar r1, UInt i2) - { -- store(mkU64(guest_IA_curr_instr + ((ULong)(Long)(Int)i2 << 1)), -- get_gpr_hw3(r1)); -+ store(mkU64(addr_rel_long(i2)), get_gpr_hw3(r1)); - - return "sthrl"; - } -@@ -13282,7 +13274,7 @@ static const HChar * - s390_irgen_EXRL(UChar r1, UInt offset) - { - IRTemp addr = newTemp(Ity_I64); -- Addr64 bytes_addr = guest_IA_curr_instr + offset * 2UL; -+ Addr64 bytes_addr = addr_rel_long(offset); - UChar *bytes = (UChar *)(HWord)bytes_addr; - /* we might save one round trip because we know the target */ - if (!last_execute_target) -diff --git a/none/tests/s390x/exrl.c b/none/tests/s390x/exrl.c -index 2c99602d8..e669e484f 100644 ---- a/none/tests/s390x/exrl.c -+++ b/none/tests/s390x/exrl.c -@@ -54,6 +54,17 @@ int main(void) - printf("|\n"); - printf("\n"); - -+ printf("------- EXRL with negative offset\n"); -+ asm volatile( "j 2f\n\t" -+ "1:\n\t" -+ "mvc 2(1,%0),0(%0)\n\t" -+ "2:\n\t" -+ "lghi 1,8\n\t" -+ ".insn ril,0xc60000000000,1,1b\n\t" // exrl 1, 1b -+ : : "a" (target) -+ : "1", "2", "3", "4"); -+ printf(" target = |%s|\n", target); -+ - return 0; - } - -diff --git a/none/tests/s390x/exrl.stdout.exp b/none/tests/s390x/exrl.stdout.exp -index 520919e92..30dcde829 100644 ---- a/none/tests/s390x/exrl.stdout.exp -+++ b/none/tests/s390x/exrl.stdout.exp -@@ -11,3 +11,5 @@ after: target = |0123456789aXXXXX| - ------- EXRL to OR in the syscall number (writes out target) - target = |0123456789aXXXXX| - -+------- EXRL with negative offset -+ target = |01010101010XXXXX| diff --git a/SPECS/valgrind.spec b/SPECS/valgrind.spec index d696689..d9ad7cb 100644 --- a/SPECS/valgrind.spec +++ b/SPECS/valgrind.spec @@ -1,12 +1,12 @@ %{?scl:%scl_package valgrind} -Summary: Tool for finding memory management bugs in programs +Summary: Dynamic analysis tools to detect memory or thread bugs and profile Name: %{?scl_prefix}valgrind -Version: 3.18.1 -Release: 7%{?dist} +Version: 3.19.0 +Release: 1%{?dist} Epoch: 1 License: GPLv2+ -URL: http://www.valgrind.org/ +URL: https://www.valgrind.org/ Group: Development/Debuggers # Only necessary for RHEL, will be ignored on Fedora @@ -78,59 +78,13 @@ Source0: https://sourceware.org/pub/valgrind/valgrind-%{version}.tar.bz2 Patch1: valgrind-3.9.0-cachegrind-improvements.patch # Make ld.so supressions slightly less specific. -Patch3: valgrind-3.9.0-ldso-supp.patch +Patch2: valgrind-3.9.0-ldso-supp.patch # Add some stack-protector -Patch4: valgrind-3.16.0-some-stack-protector.patch +Patch3: valgrind-3.16.0-some-stack-protector.patch # Add some -Wl,z,now. -Patch5: valgrind-3.16.0-some-Wl-z-now.patch - -# KDE#444495 dhat/tests/copy fails on s390x -Patch6: valgrind-3.18.1-dhat-tests-copy.patch - -# KDE#444242 s390x: Sign-extend "relative long" offset in EXRL -Patch7: valgrind-3.18.1-s390x-EXRL.patch - -# KDE#444571 - PPC, fix lxsibzx and lxsihzx -Patch8: valgrind-3.18.1-ppc64-lxsibzx-lxsihzx.patch - -# commit ae8c6de01417023e78763de145b1c0e6ddd87277 -# commit 3950c5d661ee09526cddcf24daf5fc22bc83f70c -# Fix for the prefixed stq instruction in PC relative mode. -# KDE#444836 pstq instruction for R=1 is not storing to the correct address -Patch9: valgrind-3.18.1-ppc-pstq.patch -Patch10: valgrind-3.18.1-ppc-pstq-tests.patch - -# commit 64ab89162906d5b9e2de6c3afe476fec861ef7ec -# gdbserver_tests: Filter out glibc hwcaps libc.so -Patch11: valgrind-3.18.1-gdbserver_tests-hwcap.patch - -# KDE#445184 Rust v0 symbol demangling is broken -Patch12: valgrind-3.18.1-rust-v0-demangle.patch - -# KDE#445354 arm64 backend: incorrect code emitted for doubleword CAS -Patch13: valgrind-3.18.1-arm64-doubleword-cas.patch - -# KDE#444399 arm64: unhandled instruction LD{,A}XP and ST{,L}XP -Patch14: valgrind-3.18.1-arm64-ldaxp-stlxp.patch - -# KDE#445415 arm64 front end: alignment checks missing for atomic instructions. -Patch15: valgrind-3.18.1-arm64-atomic-align.patch - -# commit 595341b150312d2407bd43304449bf39ec3e1fa8 -# amd64 front end: add more spec rules -Patch16: valgrind-3.18.1-amd64-more-spec-rules.patch - -# KDE#445504 Using C++ condition_variable results in bogus -# "mutex is locked simultaneously by two threads" warning -Patch17: valgrind-3.18.1-condvar.patch - -# KDE#445668 Inline stack frame generation is broken for Rust binaries -Patch18: valgrind-3.18.1-demangle-namespace.patch - -# KDE#449494 arm64: Mismatch detected between RDMA and atomics features -Patch19: valgrind-3.18.1-arm64-atomics-rdm.patch +Patch4: valgrind-3.16.0-some-Wl-z-now.patch BuildRequires: make BuildRequires: glibc-devel @@ -264,28 +218,14 @@ Valgrind User Manual for details. %setup -q -n %{?scl:%{pkg_name}}%{!?scl:%{name}}-%{version} %patch1 -p1 -%patch3 -p1 +%patch2 -p1 # Old rhel gcc doesn't have -fstack-protector-strong. %if 0%{?fedora} || 0%{?rhel} >= 7 +%patch3 -p1 %patch4 -p1 -%patch5 -p1 %endif -%patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 %build @@ -511,6 +451,9 @@ fi %endif %changelog +* Tue Apr 19 2022 Mark Wielaard - 3.19.0-1 +- Upgrade to valgrind 3.19.0. Drop old patches. + * Thu Feb 10 2022 Mark Wielaard - 3.18.1-7 - Add valgrind-3.18.1-arm64-atomics-rdm.patch