You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
(122) |
Nov
(152) |
Dec
(69) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
(6) |
Feb
(25) |
Mar
(73) |
Apr
(82) |
May
(24) |
Jun
(25) |
Jul
(10) |
Aug
(11) |
Sep
(10) |
Oct
(54) |
Nov
(203) |
Dec
(182) |
| 2004 |
Jan
(307) |
Feb
(305) |
Mar
(430) |
Apr
(312) |
May
(187) |
Jun
(342) |
Jul
(487) |
Aug
(637) |
Sep
(336) |
Oct
(373) |
Nov
(441) |
Dec
(210) |
| 2005 |
Jan
(385) |
Feb
(480) |
Mar
(636) |
Apr
(544) |
May
(679) |
Jun
(625) |
Jul
(810) |
Aug
(838) |
Sep
(634) |
Oct
(521) |
Nov
(965) |
Dec
(543) |
| 2006 |
Jan
(494) |
Feb
(431) |
Mar
(546) |
Apr
(411) |
May
(406) |
Jun
(322) |
Jul
(256) |
Aug
(401) |
Sep
(345) |
Oct
(542) |
Nov
(308) |
Dec
(481) |
| 2007 |
Jan
(427) |
Feb
(326) |
Mar
(367) |
Apr
(255) |
May
(244) |
Jun
(204) |
Jul
(223) |
Aug
(231) |
Sep
(354) |
Oct
(374) |
Nov
(497) |
Dec
(362) |
| 2008 |
Jan
(322) |
Feb
(482) |
Mar
(658) |
Apr
(422) |
May
(476) |
Jun
(396) |
Jul
(455) |
Aug
(267) |
Sep
(280) |
Oct
(253) |
Nov
(232) |
Dec
(304) |
| 2009 |
Jan
(486) |
Feb
(470) |
Mar
(458) |
Apr
(423) |
May
(696) |
Jun
(461) |
Jul
(551) |
Aug
(575) |
Sep
(134) |
Oct
(110) |
Nov
(157) |
Dec
(102) |
| 2010 |
Jan
(226) |
Feb
(86) |
Mar
(147) |
Apr
(117) |
May
(107) |
Jun
(203) |
Jul
(193) |
Aug
(238) |
Sep
(300) |
Oct
(246) |
Nov
(23) |
Dec
(75) |
| 2011 |
Jan
(133) |
Feb
(195) |
Mar
(315) |
Apr
(200) |
May
(267) |
Jun
(293) |
Jul
(353) |
Aug
(237) |
Sep
(278) |
Oct
(611) |
Nov
(274) |
Dec
(260) |
| 2012 |
Jan
(303) |
Feb
(391) |
Mar
(417) |
Apr
(441) |
May
(488) |
Jun
(655) |
Jul
(590) |
Aug
(610) |
Sep
(526) |
Oct
(478) |
Nov
(359) |
Dec
(372) |
| 2013 |
Jan
(467) |
Feb
(226) |
Mar
(391) |
Apr
(281) |
May
(299) |
Jun
(252) |
Jul
(311) |
Aug
(352) |
Sep
(481) |
Oct
(571) |
Nov
(222) |
Dec
(231) |
| 2014 |
Jan
(185) |
Feb
(329) |
Mar
(245) |
Apr
(238) |
May
(281) |
Jun
(399) |
Jul
(382) |
Aug
(500) |
Sep
(579) |
Oct
(435) |
Nov
(487) |
Dec
(256) |
| 2015 |
Jan
(338) |
Feb
(357) |
Mar
(330) |
Apr
(294) |
May
(191) |
Jun
(108) |
Jul
(142) |
Aug
(261) |
Sep
(190) |
Oct
(54) |
Nov
(83) |
Dec
(22) |
| 2016 |
Jan
(49) |
Feb
(89) |
Mar
(33) |
Apr
(50) |
May
(27) |
Jun
(34) |
Jul
(53) |
Aug
(53) |
Sep
(98) |
Oct
(206) |
Nov
(93) |
Dec
(53) |
| 2017 |
Jan
(65) |
Feb
(82) |
Mar
(102) |
Apr
(86) |
May
(187) |
Jun
(67) |
Jul
(23) |
Aug
(93) |
Sep
(65) |
Oct
(45) |
Nov
(35) |
Dec
(17) |
| 2018 |
Jan
(26) |
Feb
(35) |
Mar
(38) |
Apr
(32) |
May
(8) |
Jun
(43) |
Jul
(27) |
Aug
(30) |
Sep
(43) |
Oct
(42) |
Nov
(38) |
Dec
(67) |
| 2019 |
Jan
(32) |
Feb
(37) |
Mar
(53) |
Apr
(64) |
May
(49) |
Jun
(18) |
Jul
(14) |
Aug
(53) |
Sep
(25) |
Oct
(30) |
Nov
(49) |
Dec
(31) |
| 2020 |
Jan
(87) |
Feb
(45) |
Mar
(37) |
Apr
(51) |
May
(99) |
Jun
(36) |
Jul
(11) |
Aug
(14) |
Sep
(20) |
Oct
(24) |
Nov
(40) |
Dec
(23) |
| 2021 |
Jan
(14) |
Feb
(53) |
Mar
(85) |
Apr
(15) |
May
(19) |
Jun
(3) |
Jul
(14) |
Aug
(1) |
Sep
(57) |
Oct
(73) |
Nov
(56) |
Dec
(22) |
| 2022 |
Jan
(3) |
Feb
(22) |
Mar
(6) |
Apr
(55) |
May
(46) |
Jun
(39) |
Jul
(15) |
Aug
(9) |
Sep
(11) |
Oct
(34) |
Nov
(20) |
Dec
(36) |
| 2023 |
Jan
(79) |
Feb
(41) |
Mar
(99) |
Apr
(169) |
May
(48) |
Jun
(16) |
Jul
(16) |
Aug
(57) |
Sep
(19) |
Oct
|
Nov
|
Dec
|
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
|
|
|
|
|
|
|
1
(2) |
|
2
(2) |
3
(3) |
4
(3) |
5
|
6
|
7
|
8
|
|
9
|
10
(1) |
11
|
12
|
13
(2) |
14
(6) |
15
(4) |
|
16
|
17
(2) |
18
(8) |
19
(1) |
20
|
21
|
22
(2) |
|
23
|
24
(1) |
25
|
26
(3) |
27
(1) |
28
|
29
|
|
30
(2) |
|
|
|
|
|
|
|
From: Julian S. <js...@ac...> - 2018-09-24 18:21:31
|
> https://sourceware.org/git/gitweb.cgi?p=valgrind.git;h=20976f432dc5e4e2218d0fcd18ed4771d67a6d37 > > commit 20976f432dc5e4e2218d0fcd18ed4771d67a6d37 > Author: Andreas Arnez <ar...@li...> > Date: Wed Jul 25 14:23:02 2018 +0200 > > s390x: Implement conditional trap instructions > > This implements various z/Architecture instructions that conditionally > yield a data exception ("trap"). The condition is either based on a > comparison being true ("compare and trap") or on a loaded value being > zero ("load and trap"). These instructions haven't been widely used in > the past, but may now be emitted by newer compilers. Note that the > resulting signal for a data exception is SIGFPE, not SIGTRAP. Thus this > patch also adds a new jump kind Ijk_SigFPE. > > Diff: > --- > .gitignore | 1 + > VEX/priv/guest_s390_toIR.c | 307 ++++++++++++++++++++++++++++++++++++-- > VEX/priv/host_s390_defs.c | 2 + > VEX/priv/host_s390_isel.c | 6 +- > VEX/pub/libvex_ir.h | 1 + > VEX/pub/libvex_trc_values.h | 1 + > coregrind/m_scheduler/scheduler.c | 4 + > coregrind/m_signals.c | 4 +- > docs/internals/s390-opcodes.csv | 30 ++-- > none/tests/s390x/Makefile.am | 2 +- > none/tests/s390x/traps.c | 139 +++++++++++++++++ > none/tests/s390x/traps.stderr.exp | 2 + > none/tests/s390x/traps.stdout.exp | 46 ++++++ > none/tests/s390x/traps.vgtest | 1 + > 14 files changed, 511 insertions(+), 35 deletions(-) > > diff --git a/.gitignore b/.gitignore > index fc22c94..7b93983 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -1878,6 +1878,7 @@ > /none/tests/s390x/vector > /none/tests/s390x/lsc2 > /none/tests/s390x/ppno > +/none/tests/s390x/traps > > # /none/tests/scripts/ > /none/tests/scripts/*.dSYM > diff --git a/VEX/priv/guest_s390_toIR.c b/VEX/priv/guest_s390_toIR.c > index 1697e97..8f3fb6d 100644 > --- a/VEX/priv/guest_s390_toIR.c > +++ b/VEX/priv/guest_s390_toIR.c > @@ -1068,6 +1068,23 @@ gpr_w0_offset(UInt archreg) > return gpr_offset(archreg) + 0; > } > > +/* Write an integer right-aligned into a gpr. */ > +static __inline__ void > +put_gpr_int(UInt archreg, IRExpr *expr) > +{ > + UInt siz = sizeofIRType(typeOfIRExpr(irsb->tyenv, expr)); > + > + vassert(siz <= 8); > + stmt(IRStmt_Put(gpr_offset(archreg) + 8 - siz, expr)); > +} > + > +/* Read an integer of given type from a gpr. */ > +static __inline__ IRExpr * > +get_gpr_int(UInt archreg, IRType ty) > +{ > + return IRExpr_Get(gpr_offset(archreg) + 8 - sizeofIRType(ty), ty); > +} > + > /* Write word #0 of a gpr to the guest state. */ > static __inline__ void > put_gpr_w0(UInt archreg, IRExpr *expr) > @@ -2208,6 +2225,16 @@ s390_format_RIE_RRUUU(const HChar *(*irgen)(UChar r1, UChar r2, UChar i3, > } > > static void > +s390_format_RIEv1(const HChar *(*irgen)(UChar r1, UShort i2, UChar m3), > + UChar r1, UShort i2, UChar m3) > +{ > + const HChar *mnm = irgen(r1, i2, m3); > + > + if (UNLIKELY(vex_traceflags & VEX_TRACE_FE)) > + s390_disasm(ENC4(MNM, GPR, UINT, UINT), mnm, r1, i2, m3); > +} > + > +static void > s390_format_RIE_RRPU(const HChar *(*irgen)(UChar r1, UChar r2, UShort i4, > UChar m3), > UChar r1, UChar r2, UShort i4, UChar m3) > @@ -5537,6 +5564,214 @@ s390_irgen_CLGRB(UChar r1, UChar r2, UChar m3, IRTemp op4addr) > return "clgrb"; > } > > +/* Raise the appropriate signal for a compare-and-trap-instruction data > + exception if the condition is true. */ > +static void > +s390_trap_on_condition(IRExpr *cond) > +{ > + stmt(IRStmt_Exit(cond, Ijk_SigFPE, IRConst_U64(guest_IA_next_instr), > + S390X_GUEST_OFFSET(guest_IA))); > +} > + > +/* Handle the various flavors of compare (logical) and trap. */ > +static void > +s390_irgen_CxRT(UChar m3, UChar r1, UChar r2, IRType type, UInt opc) > +{ > + IRExpr *cond; > + > + if (m3 == 0) { > + /* Trap never (NOP) */ > + return; > + } else if (m3 == 14) { > + /* Trap always */ > + cond = IRExpr_Const(IRConst_U1 (True)); > + } else { > + IRTemp op1 = newTemp(type); > + IRTemp op2 = newTemp(type); > + > + assign(op1, get_gpr_int(r1, type)); > + assign(op2, get_gpr_int(r2, type)); > + cond = binop(Iop_CmpNE32, > + s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0)); > + } > + s390_trap_on_condition(cond); > +} > + > +static const HChar * > +s390_irgen_CGRT(UChar m3, UChar r1, UChar r2) > +{ > + s390_irgen_CxRT(m3, r1, r2, Ity_I64, S390_CC_OP_SIGNED_COMPARE); > + return "cgrt"; > +} > + > +static const HChar * > +s390_irgen_CRT(UChar m3, UChar r1, UChar r2) > +{ > + s390_irgen_CxRT(m3, r1, r2, Ity_I32, S390_CC_OP_SIGNED_COMPARE); > + return "crt"; > +} > + > +static const HChar * > +s390_irgen_CLGRT(UChar m3, UChar r1, UChar r2) > +{ > + s390_irgen_CxRT(m3, r1, r2, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE); > + return "clgrt"; > +} > + > +static const HChar * > +s390_irgen_CLRT(UChar m3, UChar r1, UChar r2) > +{ > + s390_irgen_CxRT(m3, r1, r2, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE); > + return "clrt"; > +} > + > +/* Handle the various flavors of compare (logical) immediate and trap. */ > +static void > +s390_irgen_CxIT(UChar m3, UChar r1, UShort i2, IRType type, UInt opc) > +{ > + IRExpr *cond; > + > + if (m3 == 0) { > + /* Trap never (NOP) */ > + return; > + } else if (m3 == 14) { > + /* Trap always */ > + cond = IRExpr_Const(IRConst_U1 (True)); > + } else { > + IRTemp op1 = newTemp(type); > + IRTemp op2 = newTemp(type); > + > + assign(op1, get_gpr_int(r1, type)); > + if (opc == S390_CC_OP_SIGNED_COMPARE) { > + assign(op2, type == Ity_I64 ? > + mkU64((ULong)(Short)i2) : mkU32((UInt)(Short)i2)); > + } else { > + assign(op2, type == Ity_I64 ? > + mkU64((ULong)i2) : mkU32((UInt)i2)); > + } > + cond = binop(Iop_CmpNE32, > + s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0)); > + } > + s390_trap_on_condition(cond); > +} > + > +static const HChar * > +s390_irgen_CGIT(UChar r1, UShort i2, UChar m3) > +{ > + s390_irgen_CxIT(m3, r1, i2, Ity_I64, S390_CC_OP_SIGNED_COMPARE); > + return "cgit"; > +} > + > +static const HChar * > +s390_irgen_CIT(UChar r1, UShort i2, UChar m3) > +{ > + s390_irgen_CxIT(m3, r1, i2, Ity_I32, S390_CC_OP_SIGNED_COMPARE); > + return "cit"; > +} > + > +static const HChar * > +s390_irgen_CLGIT(UChar r1, UShort i2, UChar m3) > +{ > + s390_irgen_CxIT(m3, r1, i2, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE); > + return "clgit"; > +} > + > +static const HChar * > +s390_irgen_CLFIT(UChar r1, UShort i2, UChar m3) > +{ > + s390_irgen_CxIT(m3, r1, i2, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE); > + return "clfit"; > +} > + > +/* Handle the variants of compare logical and trap with memory operand. */ > +static void > +s390_irgen_CLxT(UChar r1, UChar m3, IRTemp op2addr, IRType type, UInt opc) > +{ > + IRExpr *cond; > + > + if (m3 == 0) { > + /* Trap never (NOP) */ > + return; > + } else if (m3 == 14) { > + /* Trap always */ > + cond = IRExpr_Const(IRConst_U1 (True)); > + } else { > + IRTemp op1 = newTemp(type); > + IRTemp op2 = newTemp(type); > + > + assign(op1, get_gpr_int(r1, type)); > + assign(op2, load(type, mkexpr(op2addr))); > + cond = binop(Iop_CmpNE32, > + s390_call_calculate_icc(m3, opc, op1, op2), mkU32(0)); > + } > + s390_trap_on_condition(cond); > +} > + > +static const HChar * > +s390_irgen_CLT(UChar r1, UChar m3, IRTemp op2addr) > +{ > + s390_irgen_CLxT(r1, m3, op2addr, Ity_I32, S390_CC_OP_UNSIGNED_COMPARE); > + return "clt"; > +} > + > +static const HChar * > +s390_irgen_CLGT(UChar r1, UChar m3, IRTemp op2addr) > +{ > + s390_irgen_CLxT(r1, m3, op2addr, Ity_I64, S390_CC_OP_UNSIGNED_COMPARE); > + return "clgt"; > +} > + > +static const HChar * > +s390_irgen_LAT(UChar r1, IRTemp op2addr) > +{ > + IRTemp val = newTemp(Ity_I32); > + assign(val, load(Ity_I32, mkexpr(op2addr))); > + put_gpr_w1(r1, mkexpr(val)); > + s390_trap_on_condition(binop(Iop_CmpEQ32, mkexpr(val), mkU32(0))); > + return "lat"; > +} > + > +static const HChar * > +s390_irgen_LGAT(UChar r1, IRTemp op2addr) > +{ > + IRTemp val = newTemp(Ity_I64); > + assign(val, load(Ity_I64, mkexpr(op2addr))); > + put_gpr_dw0(r1, mkexpr(val)); > + s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0))); > + return "lgat"; > +} > + > +static const HChar * > +s390_irgen_LFHAT(UChar r1, IRTemp op2addr) > +{ > + IRTemp val = newTemp(Ity_I32); > + assign(val, load(Ity_I32, mkexpr(op2addr))); > + put_gpr_w0(r1, mkexpr(val)); > + s390_trap_on_condition(binop(Iop_CmpEQ32, mkexpr(val), mkU32(0))); > + return "lfhat"; > +} > + > +static const HChar * > +s390_irgen_LLGFAT(UChar r1, IRTemp op2addr) > +{ > + IRTemp val = newTemp(Ity_I64); > + assign(val, unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr)))); > + put_gpr_dw0(r1, mkexpr(val)); > + s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0))); > + return "llgfat"; > +} > + > +static const HChar * > +s390_irgen_LLGTAT(UChar r1, IRTemp op2addr) > +{ > + IRTemp val = newTemp(Ity_I64); > + assign(val, binop(Iop_And64, mkU64(0x7fffffff), > + unop(Iop_32Uto64, load(Ity_I32, mkexpr(op2addr))))); > + put_gpr_dw0(r1, mkexpr(val)); > + s390_trap_on_condition(binop(Iop_CmpEQ64, mkexpr(val), mkU64(0))); > + return "llgtat"; > +} > + > static const HChar * > s390_irgen_CLRJ(UChar r1, UChar r2, UShort i4, UChar m3) > { > @@ -16943,10 +17178,18 @@ s390_decode_4byte_and_irgen(const UChar *bytes) > case 0xb95b: s390_format_RRF_UUFR(s390_irgen_CXLFTR, ovl.fmt.RRF2.m3, > ovl.fmt.RRF2.m4, ovl.fmt.RRF2.r1, > ovl.fmt.RRF2.r2); goto ok; > - case 0xb960: /* CGRT */ goto unimplemented; > - case 0xb961: /* CLGRT */ goto unimplemented; > - case 0xb972: /* CRT */ goto unimplemented; > - case 0xb973: /* CLRT */ goto unimplemented; > + case 0xb960: s390_format_RRF_U0RR(s390_irgen_CGRT, ovl.fmt.RRF2.m3, > + ovl.fmt.RRF2.r1, ovl.fmt.RRF2.r2, > + S390_XMNM_CAB); goto ok; > + case 0xb961: s390_format_RRF_U0RR(s390_irgen_CLGRT, ovl.fmt.RRF2.m3, > + ovl.fmt.RRF2.r1, ovl.fmt.RRF2.r2, > + S390_XMNM_CAB); goto ok; > + case 0xb972: s390_format_RRF_U0RR(s390_irgen_CRT, ovl.fmt.RRF2.m3, > + ovl.fmt.RRF2.r1, ovl.fmt.RRF2.r2, > + S390_XMNM_CAB); goto ok; > + case 0xb973: s390_format_RRF_U0RR(s390_irgen_CLRT, ovl.fmt.RRF2.m3, > + ovl.fmt.RRF2.r1, ovl.fmt.RRF2.r2, > + S390_XMNM_CAB); goto ok; > case 0xb980: s390_format_RRE_RR(s390_irgen_NGR, ovl.fmt.RRE.r1, > ovl.fmt.RRE.r2); goto ok; > case 0xb981: s390_format_RRE_RR(s390_irgen_OGR, ovl.fmt.RRE.r1, > @@ -17796,7 +18039,11 @@ s390_decode_6byte_and_irgen(const UChar *bytes) > ovl.fmt.RXY.dh2); goto ok; > case 0xe30000000083ULL: /* MSGC */ goto unimplemented; > case 0xe30000000084ULL: /* MG */ goto unimplemented; > - case 0xe30000000085ULL: /* LGAT */ goto unimplemented; > + case 0xe30000000085ULL: s390_format_RXY_RRRD(s390_irgen_LGAT, ovl.fmt.RXY.r1, > + ovl.fmt.RXY.x2, ovl.fmt.RXY.b2, > + ovl.fmt.RXY.dl2, > + ovl.fmt.RXY.dh2); goto ok; > + > case 0xe30000000086ULL: s390_format_RXY_RRRD(s390_irgen_MLG, ovl.fmt.RXY.r1, > ovl.fmt.RXY.x2, ovl.fmt.RXY.b2, > ovl.fmt.RXY.dl2, > @@ -17853,9 +18100,18 @@ s390_decode_6byte_and_irgen(const UChar *bytes) > ovl.fmt.RXY.x2, ovl.fmt.RXY.b2, > ovl.fmt.RXY.dl2, > ovl.fmt.RXY.dh2); goto ok; > - case 0xe3000000009cULL: /* LLGTAT */ goto unimplemented; > - case 0xe3000000009dULL: /* LLGFAT */ goto unimplemented; > - case 0xe3000000009fULL: /* LAT */ goto unimplemented; > + case 0xe3000000009cULL: s390_format_RXY_RRRD(s390_irgen_LLGTAT, ovl.fmt.RXY.r1, > + ovl.fmt.RXY.x2, ovl.fmt.RXY.b2, > + ovl.fmt.RXY.dl2, > + ovl.fmt.RXY.dh2); goto ok; > + case 0xe3000000009dULL: s390_format_RXY_RRRD(s390_irgen_LLGFAT, ovl.fmt.RXY.r1, > + ovl.fmt.RXY.x2, ovl.fmt.RXY.b2, > + ovl.fmt.RXY.dl2, > + ovl.fmt.RXY.dh2); goto ok; > + case 0xe3000000009fULL: s390_format_RXY_RRRD(s390_irgen_LAT, ovl.fmt.RXY.r1, > + ovl.fmt.RXY.x2, ovl.fmt.RXY.b2, > + ovl.fmt.RXY.dl2, > + ovl.fmt.RXY.dh2); goto ok; > case 0xe300000000c0ULL: s390_format_RXY_RRRD(s390_irgen_LBH, ovl.fmt.RXY.r1, > ovl.fmt.RXY.x2, ovl.fmt.RXY.b2, > ovl.fmt.RXY.dl2, > @@ -17880,7 +18136,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes) > ovl.fmt.RXY.x2, ovl.fmt.RXY.b2, > ovl.fmt.RXY.dl2, > ovl.fmt.RXY.dh2); goto ok; > - case 0xe300000000c8ULL: /* LFHAT */ goto unimplemented; > + case 0xe300000000c8ULL: s390_format_RXY_RRRD(s390_irgen_LFHAT, ovl.fmt.RXY.r1, > + ovl.fmt.RXY.x2, ovl.fmt.RXY.b2, > + ovl.fmt.RXY.dl2, > + ovl.fmt.RXY.dh2); goto ok; > case 0xe300000000caULL: s390_format_RXY_RRRD(s390_irgen_LFH, ovl.fmt.RXY.r1, > ovl.fmt.RXY.x2, ovl.fmt.RXY.b2, > ovl.fmt.RXY.dl2, > @@ -18224,7 +18483,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes) > ovl.fmt.RSY.r3, ovl.fmt.RSY.b2, > ovl.fmt.RSY.dl2, > ovl.fmt.RSY.dh2); goto ok; > - case 0xeb0000000023ULL: /* CLT */ goto unimplemented; > + case 0xeb0000000023ULL: s390_format_RSY_RURD(s390_irgen_CLT, ovl.fmt.RSY.r1, > + ovl.fmt.RSY.r3, ovl.fmt.RSY.b2, > + ovl.fmt.RSY.dl2, > + ovl.fmt.RSY.dh2); goto ok; > case 0xeb0000000024ULL: s390_format_RSY_RRRD(s390_irgen_STMG, ovl.fmt.RSY.r1, > ovl.fmt.RSY.r3, ovl.fmt.RSY.b2, > ovl.fmt.RSY.dl2, > @@ -18234,7 +18496,10 @@ s390_decode_6byte_and_irgen(const UChar *bytes) > ovl.fmt.RSY.r3, ovl.fmt.RSY.b2, > ovl.fmt.RSY.dl2, > ovl.fmt.RSY.dh2); goto ok; > - case 0xeb000000002bULL: /* CLGT */ goto unimplemented; > + case 0xeb000000002bULL: s390_format_RSY_RURD(s390_irgen_CLGT, ovl.fmt.RSY.r1, > + ovl.fmt.RSY.r3, ovl.fmt.RSY.b2, > + ovl.fmt.RSY.dl2, > + ovl.fmt.RSY.dh2); goto ok; > case 0xeb000000002cULL: s390_format_RSY_RURD(s390_irgen_STCMH, > ovl.fmt.RSY.r1, ovl.fmt.RSY.r3, > ovl.fmt.RSY.b2, ovl.fmt.RSY.dl2, > @@ -18498,10 +18763,22 @@ s390_decode_6byte_and_irgen(const UChar *bytes) > ovl.fmt.RIE_RRPU.r2, > ovl.fmt.RIE_RRPU.i4, > ovl.fmt.RIE_RRPU.m3); goto ok; > - case 0xec0000000070ULL: /* CGIT */ goto unimplemented; > - case 0xec0000000071ULL: /* CLGIT */ goto unimplemented; > - case 0xec0000000072ULL: /* CIT */ goto unimplemented; > - case 0xec0000000073ULL: /* CLFIT */ goto unimplemented; > + case 0xec0000000070ULL: s390_format_RIEv1(s390_irgen_CGIT, > + ovl.fmt.RIEv1.r1, > + ovl.fmt.RIEv1.i2, > + ovl.fmt.RIEv1.m3); goto ok; > + case 0xec0000000071ULL: s390_format_RIEv1(s390_irgen_CLGIT, > + ovl.fmt.RIEv1.r1, > + ovl.fmt.RIEv1.i2, > + ovl.fmt.RIEv1.m3); goto ok; > + case 0xec0000000072ULL: s390_format_RIEv1(s390_irgen_CIT, > + ovl.fmt.RIEv1.r1, > + ovl.fmt.RIEv1.i2, > + ovl.fmt.RIEv1.m3); goto ok; > + case 0xec0000000073ULL: s390_format_RIEv1(s390_irgen_CLFIT, > + ovl.fmt.RIEv1.r1, > + ovl.fmt.RIEv1.i2, > + ovl.fmt.RIEv1.m3); goto ok; > case 0xec0000000076ULL: s390_format_RIE_RRPU(s390_irgen_CRJ, > ovl.fmt.RIE_RRPU.r1, > ovl.fmt.RIE_RRPU.r2, > diff --git a/VEX/priv/host_s390_defs.c b/VEX/priv/host_s390_defs.c > index d41093e..6c35c67 100644 > --- a/VEX/priv/host_s390_defs.c > +++ b/VEX/priv/host_s390_defs.c > @@ -6917,6 +6917,7 @@ s390_jump_kind_as_string(IRJumpKind kind) > case Ijk_InvalICache: return "Invalidate"; > case Ijk_NoRedir: return "NoRedir"; > case Ijk_SigTRAP: return "SigTRAP"; > + case Ijk_SigFPE: return "SigFPE"; > case Ijk_SigSEGV: return "SigSEGV"; > case Ijk_SigBUS: return "SigBUS"; > case Ijk_Sys_syscall: return "Sys_syscall"; > @@ -10388,6 +10389,7 @@ s390_insn_xassisted_emit(UChar *buf, const s390_insn *insn, > case Ijk_InvalICache: trcval = VEX_TRC_JMP_INVALICACHE; break; > case Ijk_NoRedir: trcval = VEX_TRC_JMP_NOREDIR; break; > case Ijk_SigTRAP: trcval = VEX_TRC_JMP_SIGTRAP; break; > + case Ijk_SigFPE: trcval = VEX_TRC_JMP_SIGFPE; 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_s390_isel.c b/VEX/priv/host_s390_isel.c > index ab71afe..dec1259 100644 > --- a/VEX/priv/host_s390_isel.c > +++ b/VEX/priv/host_s390_isel.c > @@ -4441,7 +4441,8 @@ no_memcpy_put: > case Ijk_ClientReq: > case Ijk_NoRedir: > case Ijk_Yield: > - case Ijk_SigTRAP: { > + case Ijk_SigTRAP: > + case Ijk_SigFPE: { > HReg dst = s390_isel_int_expr(env, IRExpr_Const(stmt->Ist.Exit.dst)); > addInstr(env, s390_insn_xassisted(cond, dst, guest_IA, > stmt->Ist.Exit.jk)); > @@ -4556,7 +4557,8 @@ iselNext(ISelEnv *env, IRExpr *next, IRJumpKind jk, Int offsIP) > case Ijk_ClientReq: > case Ijk_NoRedir: > case Ijk_Yield: > - case Ijk_SigTRAP: { > + case Ijk_SigTRAP: > + case Ijk_SigFPE: { > HReg dst = s390_isel_int_expr(env, next); > addInstr(env, s390_insn_xassisted(S390_CC_ALWAYS, dst, guest_IA, jk)); > return; > diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h > index 2b07afd..4beaabd 100644 > --- a/VEX/pub/libvex_ir.h > +++ b/VEX/pub/libvex_ir.h > @@ -2378,6 +2378,7 @@ typedef > Ijk_SigTRAP, /* current instruction synths SIGTRAP */ > Ijk_SigSEGV, /* current instruction synths SIGSEGV */ > Ijk_SigBUS, /* current instruction synths SIGBUS */ > + Ijk_SigFPE, /* current instruction synths generic SIGFPE */ > Ijk_SigFPE_IntDiv, /* current instruction synths SIGFPE - IntDiv */ > Ijk_SigFPE_IntOvf, /* current instruction synths SIGFPE - IntOvf */ > /* Unfortunately, various guest-dependent syscall kinds. They > diff --git a/VEX/pub/libvex_trc_values.h b/VEX/pub/libvex_trc_values.h > index e46e0fb..fb879b1 100644 > --- a/VEX/pub/libvex_trc_values.h > +++ b/VEX/pub/libvex_trc_values.h > @@ -58,6 +58,7 @@ > #define VEX_TRC_JMP_SIGSEGV 87 /* deliver segv (SIGSEGV) before > continuing */ > #define VEX_TRC_JMP_SIGBUS 93 /* deliver SIGBUS before continuing */ > +#define VEX_TRC_JMP_SIGFPE 105 /* deliver SIGFPE before continuing */ > > #define VEX_TRC_JMP_SIGFPE_INTDIV 97 /* deliver SIGFPE (integer divide > by zero) before continuing */ > diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c > index 87cb4d6..68e9590 100644 > --- a/coregrind/m_scheduler/scheduler.c > +++ b/coregrind/m_scheduler/scheduler.c > @@ -1591,6 +1591,10 @@ VgSchedReturnCode VG_(scheduler) ( ThreadId tid ) > VG_(synth_sigbus)(tid); > break; > > + case VEX_TRC_JMP_SIGFPE: > + VG_(synth_sigfpe)(tid, 0); > + break; > + > case VEX_TRC_JMP_SIGFPE_INTDIV: > VG_(synth_sigfpe)(tid, VKI_FPE_INTDIV); > break; > diff --git a/coregrind/m_signals.c b/coregrind/m_signals.c > index e158fe3..e572f17 100644 > --- a/coregrind/m_signals.c > +++ b/coregrind/m_signals.c > @@ -2157,8 +2157,8 @@ void VG_(synth_sigtrap)(ThreadId tid) > // Synthesise a SIGFPE. > void VG_(synth_sigfpe)(ThreadId tid, UInt code) > { > -// Only tested on mips32 and mips64 > -#if !defined(VGA_mips32) && !defined(VGA_mips64) > +// Only tested on mips32, mips64, and s390x > +#if !defined(VGA_mips32) && !defined(VGA_mips64) && !defined(VGA_s390x) > vg_assert(0); > #else > vki_siginfo_t info; > diff --git a/docs/internals/s390-opcodes.csv b/docs/internals/s390-opcodes.csv > index 36becfd..fe84a7c 100644 > --- a/docs/internals/s390-opcodes.csv > +++ b/docs/internals/s390-opcodes.csv > @@ -759,10 +759,10 @@ cib,"compare immediate and branch (32<8)",implemented, > cgib,"compare immediate and branch (64<8)",implemented, > cij,"compare immediate and branch relative (32<8)",implemented, > cgij,"compare immediate and branch relative (64<8)",implemented, > -crt,"compare and trap","not implemented","issued by gcc" > -cgrt,"compare and trap 64","not implemented","issued by gcc" > -cit,"compare immediate and trap (32<16)","not implemented","issued by gcc" > -cgit,"compare immediate and trap (64<16)","not implemented","issued by gcc" > +crt,"compare and trap",implemented, > +cgrt,"compare and trap 64",implemented, > +cit,"compare immediate and trap (32<16)",implemented, > +cgit,"compare immediate and trap (64<16)",implemented, > cgh,"compare halfword (64<16)",implemented, > chhsi,"compare halfword immediate (16<16)",implemented, > chsi,"compare halfword immediate (32<16)",implemented, > @@ -785,10 +785,10 @@ clib,"compare logical immediate and branch (32<8)",implemented, > clgib,"compare logical immediate and branch (64<8)",implemented, > clij,"compare logical immediate and branch relative (32<8)",implemented, > clgij,"compare logical immediate and branch relative (64<8)",implemented, > -clrt,"compare logical and trap (32)","not implemented", > -clgrt,"compare logical and trap (64)","not implemented", > -clfit,"compare logical and trap (32<16)","not implemented", > -clgit,"compare logical and trap (64<16)","not implemented", > +clrt,"compare logical and trap (32)",implemented, > +clgrt,"compare logical and trap (64)",implemented, > +clfit,"compare logical and trap (32<16)",implemented, > +clgit,"compare logical and trap (64<16)",implemented, > ecag,"extract cache attribute",implemented, > lrl,"load relative long (32)",implemented, > lgrl,"load relative long (64)",implemented, > @@ -968,13 +968,13 @@ bprp,"branch prediction relative preload","not implemented",zEC12, > ppa,"perform processor assist","not implemented",zEC12, > niai,"next instruction access intent","not implemented",zEC12, > crdte,"compare and replace DAT table entry",N/A,"privileged instruction" > -lat,"load and trap 32 bit","not implemented",zEC12, > -lgat,"load and trap 64 bit","not implemented",zEC12, > -lfhat,"load high and trap","not implemented",zEC12, > -llgfat,"load logical and trap 32>64","not implemented",zEC12, > -llgtat,"load logical thirty one bits and trap 31>64","not implemented",zEC12, > -clt,"compare logical and trap 32 bit reg-mem","not implemented",zEC12, > -clgt,"compare logical and trap 64 bit reg-mem","not implemented",zEC12, > +lat,"load and trap 32 bit",implemented,zEC12, > +lgat,"load and trap 64 bit",implemented,zEC12, > +lfhat,"load high and trap",implemented,zEC12, > +llgfat,"load logical and trap 32>64",implemented,zEC12, > +llgtat,"load logical thirty one bits and trap 31>64",implemented,zEC12, > +clt,"compare logical and trap 32 bit reg-mem",implemented,zEC12, > +clgt,"compare logical and trap 64 bit reg-mem",implemented,zEC12, > risbgn,"rotate then insert selected bits nocc",implemented,zEC12, > cdzt,"convert from zoned long","not implemented",zEC12, > cxzt,"convert from zoned extended","not implemented",zEC12, > diff --git a/none/tests/s390x/Makefile.am b/none/tests/s390x/Makefile.am > index 29cd6a3..ff9c291 100644 > --- a/none/tests/s390x/Makefile.am > +++ b/none/tests/s390x/Makefile.am > @@ -12,7 +12,7 @@ INSN_TESTS = clc clcle cvb cvd icm lpr tcxb lam_stam xc mvst add sub mul \ > rounding-1 rounding-2 rounding-3 rounding-4 rounding-5 bfp-1 \ > bfp-2 bfp-3 bfp-4 srnm srnmb comp-1 comp-2 exrl tmll tm stmg \ > ex clst mvc test_fork test_sig rounding-6 rxsbg popcnt \ > - high-word \ > + high-word traps \ > spechelper-alr spechelper-algr \ > spechelper-slr spechelper-slgr \ > spechelper-cr spechelper-clr \ > diff --git a/none/tests/s390x/traps.c b/none/tests/s390x/traps.c > new file mode 100644 > index 0000000..86874c3 > --- /dev/null > +++ b/none/tests/s390x/traps.c > @@ -0,0 +1,139 @@ > +#include <features.h> > +#include <fpu_control.h> > +#include <signal.h> > +#include <sys/types.h> > +#include <signal.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <ucontext.h> > +#include <unistd.h> > + > +#define MSK_NEVER 0x0 > +#define MSK_GT 0x2 > +#define MSK_LT 0x4 > +#define MSK_NE 0x6 > +#define MSK_EQ 0x8 > +#define MSK_GE 0xa > +#define MSK_LE 0xc > +#define MSK_ALWAYS 14 > + > +#define str(a) #a > + > +static const char *msk_op[] = { > + "N", ">", "<", "!=", "==", ">=", "<=", "Y" > +}; > + > +static void handle_sigfpe(int sig, siginfo_t *info, void *uc) > +{ > + printf(" [FPE %d]", info->si_code); > + fflush(stdout); > +} > + > +/* Load and trap. */ > + > +#define test_LxAT(type,mnem,opc) \ > + { \ > + static const type vals[] = { \ > + 0x12345678, -0x12345678, 0x80000000, 0 \ > + }; \ > + int i; \ > + printf("%-6s", mnem); fflush(stdout); \ > + for (i = 0; i < sizeof(vals) / sizeof(vals[0]); i++) { \ > + unsigned long result; \ > + asm volatile("lghi %[out], -1\n" \ > + ".insn rxy, 0x" opc ",%[out],%[in]\n" \ > + : [out] "=&d" (result) : [in] "R" (vals[i])); \ > + printf(" %016lx", result); \ > + } \ > + putchar('\n'); \ > + } > + > +/* Compare and trap, register/register. */ > + > +#define insn_CxRT(type,fmt,opc,mask,a_val,b_val) { \ > + type a = a_val; \ > + type b = b_val; \ > + printf(" " fmt " %s " fmt, a, msk_op[mask / 2], b); \ > + fflush(stdout); \ > + asm volatile(".insn rrf, 0x" opc "0000,%[a],%[b]," str(mask) ",0\n" \ > + : : [a] "d" (a), [b] "d" (b)); \ > + putchar('\n'); \ > + } > + > +#define test_CxRT(type,fmt,mnem,opc) { \ > + printf("%s:\n", mnem); \ > + insn_CxRT(type, fmt, opc, MSK_ALWAYS, 0, 0); \ > + insn_CxRT(type, fmt, opc, MSK_LT, 1, -1); \ > + insn_CxRT(type, fmt, opc, MSK_GT, 0x7fffffff, -0x80000000); \ > + } > + > +/* Compare and trap, register/immediate. */ > + > +#define insn_CxIT(sign,type,fmt,opc1,opc2,mask,val,imm) { \ > + sign type a = val; \ > + printf(" " fmt " %s " fmt, a, msk_op[mask / 2], \ > + (sign type)(sign short) imm); \ > + fflush(stdout); \ > + asm volatile(".insn ri, 0x" opc1 "000000,%[a]," str(imm) "\n" \ > + ".byte " str(mask) "*16, 0x" opc2 "\n" \ > + : : [a] "d" (a)); \ > + putchar('\n'); \ > + } > + > +#define test_CxIT(sign,type,fmt,mnem,opc1,opc2) { \ > + printf("%s:\n", mnem); \ > + insn_CxIT(sign, type, fmt, opc1, opc2, MSK_NEVER, 0, 0); \ > + insn_CxIT(sign, type, fmt, opc1, opc2, MSK_NE, -1, -1); \ > + insn_CxIT(sign, type, fmt, opc1, opc2, MSK_LE, -0x80000000, 41); \ > + } > + > +/* Compare and trap, register/memory. */ > + > +#define insn_CLxT(type,fmt,opc1,opc2,mask,a_val,b_val) { \ > + type a = a_val; \ > + type b = b_val; \ > + printf(" " fmt " %s " fmt, a, msk_op[mask / 2], b); \ > + fflush(stdout); \ > + asm volatile(".insn rsy, 0x" opc1 "00000000" opc2 ",%[a]," \ > + str(mask) ",%[b]\n" : : [a] "d" (a), [b] "R" (b)); \ > + putchar('\n'); \ > + } > + > +#define test_CLxT(type,fmt,mnem,opc1,opc2) { \ > + printf("%s:\n", mnem); \ > + insn_CLxT(type, fmt, opc1, opc2, MSK_GE, 1, -1); \ > + insn_CLxT(type, fmt, opc1, opc2, MSK_EQ, 0xffffffff, -1); \ > + } > + > +int main(void) > +{ > + struct sigaction sa; > + > + sa.sa_sigaction = handle_sigfpe; > + sa.sa_flags = SA_SIGINFO; > + sigemptyset(&sa.sa_mask); > + sigaction(SIGFPE, &sa, NULL); > + > + test_LxAT(unsigned, "lat", "e3000000009f"); > + test_LxAT(unsigned long, "lgat", "e30000000085"); > + test_LxAT(unsigned, "lfhat", "e300000000c8"); > + test_LxAT(unsigned, "llgfat", "e3000000009d"); > + test_LxAT(unsigned, "llgtat", "e3000000009c"); > + > + putchar('\n'); > + test_CxRT(int, "%d", "crt", "b972"); > + test_CxRT(unsigned int, "%u", "clrt", "b973"); > + test_CxRT(long int, "%ld", "cgrt", "b960"); > + test_CxRT(unsigned long, "%lu", "clgrt", "b961"); > + > + putchar('\n'); > + test_CxIT(signed, int, "%d", "cit", "ec", "72"); > + test_CxIT(unsigned, int, "%u", "clfit", "ec", "73"); > + test_CxIT(signed, long, "%ld", "cgit", "ec", "70"); > + test_CxIT(unsigned, long, "%lu", "clgit", "ec", "71"); > + > + putchar('\n'); > + test_CLxT(unsigned int, "%u", "clt", "eb", "23"); > + test_CLxT(unsigned long, "%lu", "clgt", "eb", "2b"); > + return 0; > +} > diff --git a/none/tests/s390x/traps.stderr.exp b/none/tests/s390x/traps.stderr.exp > new file mode 100644 > index 0000000..139597f > --- /dev/null > +++ b/none/tests/s390x/traps.stderr.exp > @@ -0,0 +1,2 @@ > + > + > diff --git a/none/tests/s390x/traps.stdout.exp b/none/tests/s390x/traps.stdout.exp > new file mode 100644 > index 0000000..59a55b3 > --- /dev/null > +++ b/none/tests/s390x/traps.stdout.exp > @@ -0,0 +1,46 @@ > +lat ffffffff12345678 ffffffffedcba988 ffffffff80000000 [FPE 0] ffffffff00000000 > +lgat 0000000012345678 ffffffffedcba988 0000000080000000 [FPE 0] 0000000000000000 > +lfhat 12345678ffffffff edcba988ffffffff 80000000ffffffff [FPE 0] 00000000ffffffff > +llgfat 0000000012345678 00000000edcba988 0000000080000000 [FPE 0] 0000000000000000 > +llgtat 0000000012345678 000000006dcba988 [FPE 0] 0000000000000000 [FPE 0] 0000000000000000 > + > +crt: > + 0 Y 0 [FPE 0] > + 1 < -1 > + 2147483647 > -2147483648 [FPE 0] > +clrt: > + 0 Y 0 [FPE 0] > + 1 < 4294967295 [FPE 0] > + 2147483647 > 2147483648 > +cgrt: > + 0 Y 0 [FPE 0] > + 1 < -1 > + 2147483647 > 2147483648 > +clgrt: > + 0 Y 0 [FPE 0] > + 1 < 18446744073709551615 [FPE 0] > + 2147483647 > 2147483648 > + > +cit: > + 0 N 0 > + -1 != -1 > + -2147483648 <= 41 [FPE 0] > +clfit: > + 0 N 0 > + 4294967295 != 65535 [FPE 0] > + 2147483648 <= 41 > +cgit: > + 0 N 0 > + -1 != -1 > + 2147483648 <= 41 > +clgit: > + 0 N 0 > + 18446744073709551615 != 65535 [FPE 0] > + 2147483648 <= 41 > + > +clt: > + 1 >= 4294967295 > + 4294967295 == 4294967295 [FPE 0] > +clgt: > + 1 >= 18446744073709551615 > + 4294967295 == 18446744073709551615 > diff --git a/none/tests/s390x/traps.vgtest b/none/tests/s390x/traps.vgtest > new file mode 100644 > index 0000000..e46fb15 > --- /dev/null > +++ b/none/tests/s390x/traps.vgtest > @@ -0,0 +1 @@ > +prog: traps > > ---------- |