1
2
3
4
5
6
7
8
9
10
11
12
13#include "qemu/osdep.h"
14#include "qemu/main-loop.h"
15#include "internal.h"
16#include "tcg_s390x.h"
17#include "exec/helper-proto.h"
18#include "exec/exec-all.h"
19#include "exec/cpu_ldst.h"
20
21uint32_t HELPER(msa)(CPUS390XState *env, uint32_t r1, uint32_t r2, uint32_t r3,
22 uint32_t type)
23{
24 const uintptr_t ra = GETPC();
25 const uint8_t mod = env->regs[0] & 0x80ULL;
26 const uint8_t fc = env->regs[0] & 0x7fULL;
27 uint8_t subfunc[16] = { 0 };
28 uint64_t param_addr;
29 int i;
30
31 switch (type) {
32 case S390_FEAT_TYPE_KMAC:
33 case S390_FEAT_TYPE_KIMD:
34 case S390_FEAT_TYPE_KLMD:
35 case S390_FEAT_TYPE_PCKMO:
36 case S390_FEAT_TYPE_PCC:
37 if (mod) {
38 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
39 }
40 break;
41 }
42
43 s390_get_feat_block(type, subfunc);
44 if (!test_be_bit(fc, subfunc)) {
45 tcg_s390_program_interrupt(env, PGM_SPECIFICATION, ra);
46 }
47
48 switch (fc) {
49 case 0:
50 for (i = 0; i < 16; i++) {
51 param_addr = wrap_address(env, env->regs[1] + i);
52 cpu_stb_data_ra(env, param_addr, subfunc[i], ra);
53 }
54 break;
55 default:
56
57 g_assert_not_reached();
58 }
59
60 return 0;
61}
62