target-s390: Implement SAM specification exception

Also, these are user-mode instructions; allow their use
in CONFIG_USER_ONLY.

Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Richard Henderson 2013-09-06 09:31:37 -07:00
parent 16017c4854
commit 8612c93583
2 changed files with 31 additions and 8 deletions

View File

@ -566,6 +566,10 @@
/* SET ACCESS */ /* SET ACCESS */
C(0xb24e, SAR, RRE, Z, 0, r2_o, 0, 0, sar, 0) C(0xb24e, SAR, RRE, Z, 0, r2_o, 0, 0, sar, 0)
/* SET ADDRESSING MODE */
D(0x010c, SAM24, E, Z, 0, 0, 0, 0, sam, 0, 0)
D(0x010d, SAM31, E, Z, 0, 0, 0, 0, sam, 0, 1)
D(0x010e, SAM64, E, Z, 0, 0, 0, 0, sam, 0, 3)
/* SET FPC */ /* SET FPC */
C(0xb384, SFPC, RRE, Z, 0, r1_o, 0, 0, sfpc, 0) C(0xb384, SFPC, RRE, Z, 0, r1_o, 0, 0, sfpc, 0)
/* SET FPC AND SIGNAL */ /* SET FPC AND SIGNAL */
@ -743,10 +747,6 @@
C(0xb22a, RRBE, RRE, Z, 0, r2_o, 0, 0, rrbe, 0) C(0xb22a, RRBE, RRE, Z, 0, r2_o, 0, 0, rrbe, 0)
/* SERVICE CALL LOGICAL PROCESSOR (PV hypercall) */ /* SERVICE CALL LOGICAL PROCESSOR (PV hypercall) */
C(0xb220, SERVC, RRE, Z, r1_o, r2_o, 0, 0, servc, 0) C(0xb220, SERVC, RRE, Z, r1_o, r2_o, 0, 0, servc, 0)
/* SET ADDRESSING MODE */
D(0x010c, SAM24, E, Z, 0, 0, 0, 0, sam, 0, 0)
D(0x010d, SAM31, E, Z, 0, 0, 0, 0, sam, 0, 1)
D(0x010e, SAM64, E, Z, 0, 0, 0, 0, sam, 0, 3)
/* SET ADDRESS SPACE CONTROL FAST */ /* SET ADDRESS SPACE CONTROL FAST */
C(0xb279, SACF, S, Z, 0, a2, 0, 0, sacf, 0) C(0xb279, SACF, S, Z, 0, a2, 0, 0, sacf, 0)
/* SET CLOCK */ /* SET CLOCK */

View File

@ -2925,19 +2925,42 @@ static ExitStatus op_sacf(DisasContext *s, DisasOps *o)
/* Addressing mode has changed, so end the block. */ /* Addressing mode has changed, so end the block. */
return EXIT_PC_STALE; return EXIT_PC_STALE;
} }
#endif
static ExitStatus op_sam(DisasContext *s, DisasOps *o) static ExitStatus op_sam(DisasContext *s, DisasOps *o)
{ {
int sam = s->insn->data; int sam = s->insn->data;
TCGv_i64 tsam = tcg_const_i64(sam); TCGv_i64 tsam;
uint64_t mask;
/* Overwrite PSW_MASK_64 and PSW_MASK_32 */ switch (sam) {
case 0:
mask = 0xffffff;
break;
case 1:
mask = 0x7fffffff;
break;
default:
mask = -1;
break;
}
/* Bizzare but true, we check the address of the current insn for the
specification exception, not the next to be executed. Thus the PoO
documents that Bad Things Happen two bytes before the end. */
if (s->pc & ~mask) {
gen_program_exception(s, PGM_SPECIFICATION);
return EXIT_NORETURN;
}
s->next_pc &= mask;
tsam = tcg_const_i64(sam);
tcg_gen_deposit_i64(psw_mask, psw_mask, tsam, 31, 2); tcg_gen_deposit_i64(psw_mask, psw_mask, tsam, 31, 2);
tcg_temp_free_i64(tsam); tcg_temp_free_i64(tsam);
/* Always exit the TB, since we (may have) changed execution mode. */
return EXIT_PC_STALE; return EXIT_PC_STALE;
} }
#endif
static ExitStatus op_sar(DisasContext *s, DisasOps *o) static ExitStatus op_sar(DisasContext *s, DisasOps *o)
{ {