target/s390x: fix CSST decoding and runtime alignment check
CSST is defined as:
C(0xc802, CSST, SSF, CASS, la1, a2, 0, 0, csst, 0)
It means that the first parameter is handled by in1_la1().
in1_la1() fills addr1 field, and not in1.
Furthermore, when extract32() is used for the alignment check, the
third parameter should specify the number of trailing bits that must
be 0. For FC these numbers are:
FC=0 (word, 4 bytes): 2
FC=1 (double word, 8 bytes): 3
FC=2 (quad word, 16 bytes): 4
For SC these numbers correspond to the size:
SC=0: 0
SC=1: 1
SC=2: 2
SC=3: 3
SC=4: 4
Signed-off-by: Pavel Zbitskiy <pavel.zbitskiy@gmail.com>
Message-Id: <20180821025104.19604-4-pavel.zbitskiy@gmail.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-08-21 04:51:00 +02:00
|
|
|
#include <stdint.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
int main(void)
|
|
|
|
{
|
2019-06-10 03:42:49 +02:00
|
|
|
uint64_t parmlist[] __attribute__((aligned(16))) = {
|
target/s390x: fix CSST decoding and runtime alignment check
CSST is defined as:
C(0xc802, CSST, SSF, CASS, la1, a2, 0, 0, csst, 0)
It means that the first parameter is handled by in1_la1().
in1_la1() fills addr1 field, and not in1.
Furthermore, when extract32() is used for the alignment check, the
third parameter should specify the number of trailing bits that must
be 0. For FC these numbers are:
FC=0 (word, 4 bytes): 2
FC=1 (double word, 8 bytes): 3
FC=2 (quad word, 16 bytes): 4
For SC these numbers correspond to the size:
SC=0: 0
SC=1: 1
SC=2: 2
SC=3: 3
SC=4: 4
Signed-off-by: Pavel Zbitskiy <pavel.zbitskiy@gmail.com>
Message-Id: <20180821025104.19604-4-pavel.zbitskiy@gmail.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
2018-08-21 04:51:00 +02:00
|
|
|
0xfedcba9876543210ull,
|
|
|
|
0,
|
|
|
|
0x7777777777777777ull,
|
|
|
|
0,
|
|
|
|
};
|
|
|
|
uint64_t op1 = 0x0123456789abcdefull;
|
|
|
|
uint64_t op2 = 0;
|
|
|
|
uint64_t op3 = op1;
|
|
|
|
uint64_t cc;
|
|
|
|
|
|
|
|
asm volatile(
|
|
|
|
" lghi %%r0,%[flags]\n"
|
|
|
|
" la %%r1,%[parmlist]\n"
|
|
|
|
" csst %[op1],%[op2],%[op3]\n"
|
|
|
|
" ipm %[cc]\n"
|
|
|
|
: [op1] "+m" (op1),
|
|
|
|
[op2] "+m" (op2),
|
|
|
|
[op3] "+r" (op3),
|
|
|
|
[cc] "=r" (cc)
|
|
|
|
: [flags] "K" (0x0301),
|
|
|
|
[parmlist] "m" (parmlist)
|
|
|
|
: "r0", "r1", "cc", "memory");
|
|
|
|
cc = (cc >> 28) & 3;
|
|
|
|
if (cc) {
|
|
|
|
write(1, "bad cc\n", 7);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (op1 != parmlist[0]) {
|
|
|
|
write(1, "bad op1\n", 8);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
if (op2 != parmlist[2]) {
|
|
|
|
write(1, "bad op2\n", 8);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|