On 21.08.2018 04:51, Pavel Zbitskiy wrote: > PACK fails on the test from the Principles of Operation: F1F2F3F4 > becomes 0000234C instead of 0001234C due to an off-by-one error. > Furthermore, it overwrites one extra byte to the left of F1. > > If len_dest is 0, then we only want to flip the 1st byte and never loop > over the rest. Therefore, the loop condition should be > and not >=. > > If len_src is 1, then we should flip the 1st byte and pack the 2nd. > Since len_src is already decremented before the loop, the first > condition should be >=, and not >. > > Likewise for len_src == 2 and the second condition. > > Signed-off-by: Pavel Zbitskiy <pavel.zbits...@gmail.com> > --- > target/s390x/mem_helper.c | 6 +++--- > tests/tcg/s390x/Makefile.target | 1 + > tests/tcg/s390x/pack.c | 21 +++++++++++++++++++++ > 3 files changed, 25 insertions(+), 3 deletions(-) > create mode 100644 tests/tcg/s390x/pack.c > > diff --git a/target/s390x/mem_helper.c b/target/s390x/mem_helper.c > index 704d0193b5..bacae4f503 100644 > --- a/target/s390x/mem_helper.c > +++ b/target/s390x/mem_helper.c > @@ -1019,15 +1019,15 @@ void HELPER(pack)(CPUS390XState *env, uint32_t len, > uint64_t dest, uint64_t src) > len_src--; > > /* now pack every value */ > - while (len_dest >= 0) { > + while (len_dest > 0) { > b = 0; > > - if (len_src > 0) { > + if (len_src >= 0) { > b = cpu_ldub_data_ra(env, src, ra) & 0x0f; > src--; > len_src--; > } > - if (len_src > 0) { > + if (len_src >= 0) { > b |= cpu_ldub_data_ra(env, src, ra) << 4; > src--; > len_src--; > diff --git a/tests/tcg/s390x/Makefile.target b/tests/tcg/s390x/Makefile.target > index 7de4376f52..151dc075aa 100644 > --- a/tests/tcg/s390x/Makefile.target > +++ b/tests/tcg/s390x/Makefile.target > @@ -5,3 +5,4 @@ TESTS+=csst > TESTS+=ipm > TESTS+=exrl-trt > TESTS+=exrl-trtr > +TESTS+=pack > diff --git a/tests/tcg/s390x/pack.c b/tests/tcg/s390x/pack.c > new file mode 100644 > index 0000000000..4be36f29a7 > --- /dev/null > +++ b/tests/tcg/s390x/pack.c > @@ -0,0 +1,21 @@ > +#include <unistd.h> > + > +int main(void) > +{ > + char data[] = {0xaa, 0xaa, 0xf1, 0xf2, 0xf3, 0xc4, 0xaa, 0xaa}; > + char exp[] = {0xaa, 0xaa, 0x00, 0x01, 0x23, 0x4c, 0xaa, 0xaa}; > + int i; > + > + asm volatile( > + " pack 2(4,%[data]),2(4,%[data])\n" > + : > + : [data] "r" (&data[0]) > + : "memory"); > + for (i = 0; i < 8; i++) { > + if (data[i] != exp[i]) { > + write(1, "bad data\n", 9); > + return 1; > + } > + } > + return 0; > +} > Reviewed-by: David Hildenbrand <da...@redhat.com>
-- Thanks, David / dhildenb