Merge branch 's390-reorg' of git://repo.or.cz/qemu/rth

* 's390-reorg' of git://repo.or.cz/qemu/rth: (149 commits)
  target-s390: Claim maintainership
  target-s390: Use noreturn for exception and load_psw
  target-s390: Use TCG_CALL_NO_WG for misc helpers
  target-s390: Use TCG_CALL_NO_WG for integer helpers
  target-s390: Use TCG_CALL_NO_WG for floating-point helpers
  target-s390: Use TCG_CALL_NO_WG for memory helpers
  target-s390: Perform COMPARE AND SWAP inline
  target-s390: Optimize get_address
  target-s390: Optimize ADDC/SUBB
  target-s390: Optimize ADDU/SUBU CC testing
  target-s390: Tidy comparisons
  target-s390: Optmize emitting discards
  target-s390: Optimize XC
  target-s390: Fix cpu_clone_regs
  target-s390: Implement LOAD/SET FP AND SIGNAL
  target-s390: Implement SET ROUNDING MODE
  target-s390: Use uint64_to_float128
  target-s390: Implement LCDFR
  target-s390: Check insn operand specifications
  target-s390: Implement CPSDR
  ...
This commit is contained in:
Blue Swirl 2013-01-12 12:46:57 +00:00
commit 837d1f9782
16 changed files with 6451 additions and 6080 deletions

View File

@ -98,6 +98,7 @@ S: Maintained
F: target-ppc/
S390
M: Richard Henderson <rth@twiddle.net>
M: Alexander Graf <agraf@suse.de>
S: Maintained
F: target-s390x/

View File

@ -589,6 +589,16 @@ static const struct s390_operand s390_operands[] =
{ 4, 32, S390_OPERAND_CCODE },
#define I8_32 46 /* 8 bit signed value starting at 32 */
{ 8, 32, S390_OPERAND_SIGNED },
#define U8_24 47 /* 8 bit unsigned value starting at 24 */
{ 8, 24, 0 },
#define U8_32 48 /* 8 bit unsigned value starting at 32 */
{ 8, 32, 0 },
#define I16_32 49
{ 16, 32, S390_OPERAND_SIGNED },
#define M4_16 50 /* 4-bit condition-code starting at 12 */
{ 4, 16, S390_OPERAND_CCODE },
#define I8_16 51
{ 8, 16, S390_OPERAND_SIGNED },
/* QEMU-END */
};
@ -663,7 +673,9 @@ static const struct s390_operand s390_operands[] =
This is just a workaround for existing code e.g. glibc. */
#define INSTR_RRE_RR_OPT 4, { R_24,RO_28,0,0,0,0 } /* efpc, sfpc */
#define INSTR_RRF_F0FF 4, { F_16,F_24,F_28,0,0,0 } /* e.g. madbr */
#define INSTR_RRF_F0FF2 4, { F_24,F_16,F_28,0,0,0 } /* e.g. cpsdr */
/* QEMU-MOD */
#define INSTR_RRF_F0FF2 4, { F_24,F_28,F_16,0,0,0 } /* e.g. cpsdr */
/* QEMU-END */
#define INSTR_RRF_F0FR 4, { F_24,F_16,R_28,0,0,0 } /* e.g. iedtr */
#define INSTR_RRF_FUFF 4, { F_24,F_16,F_28,U4_20,0,0 } /* e.g. didbr */
#define INSTR_RRF_RURR 4, { R_24,R_28,R_16,U4_20,0,0 } /* e.g. .insn */
@ -801,11 +813,35 @@ static const struct s390_operand s390_operands[] =
#define MASK_SSF_RRDRD { 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00 }
/* QEMU-ADD: */
#define INSTR_RIE_MRRP 6, { M4_32,R_8,R_12,J16_16,0,0 } /* e.g. crj */
#define INSTR_RIE_MRRP 6, { M4_32, R_8, R_12, J16_16, 0, 0 } /* e.g. crj */
#define MASK_RIE_MRRP { 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff }
#define INSTR_RIE_MRIP 6, { M4_12,R_8,I8_32,J16_16,0,0 } /* e.g. cij */
#define INSTR_RIE_MRIP 6, { M4_12, R_8, I8_32, J16_16, 0, 0 } /* e.g. cij */
#define MASK_RIE_MRIP { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
#define INSTR_RIE_RRIII 6, { R_8, R_12, U8_16, U8_24, U8_32, 0 } /* risbg */
#define MASK_RIE_RRIII { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
#define INSTR_RIE_MRI 6, { M4_32, R_8, I16_16, 0, 0, 0 } /* e.g. cit */
#define MASK_RIE_MRI { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
#define INSTR_RIE_MRU 6, { M4_32, R_8, U16_16, 0, 0, 0 } /* e.g. clfit */
#define MASK_RIE_MRU { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
#define INSTR_RIE_RRI 6, { R_8, R_12, I16_16, 0, 0, 0 }
#define MASK_RIE_RRI { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
#define INSTR_RXY_URRD 6, { U8_8, D20_20, X_12, B_16, 0, 0 }
#define MASK_RXY_URRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
#define INSTR_SIL_DRI 6, { D_20, B_16, I16_32, 0, 0, 0 }
#define MASK_SIL_DRI { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
#define INSTR_RSY_MRRD 6, { M4_12, R_8, D20_20, B_16, 0, 0 }
#define MASK_SRY_MRRD { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
#define INSTR_RRF_MRR 6, { M4_16, R_24, R_28, 0, 0, 0 }
#define MASK_RRF_MRR { 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }
#define INSTR_SIY_DRI 6, { D20_20, B_16, I8_16, 0, 0, 0 }
#define MASK_SIY_DRI { 0xff, 0x00, 0x00, 0x00, 0x00, 0xff }
/* QEMU-END */
/* The opcode formats table (blueprints for .insn pseudo mnemonic). */
@ -926,6 +962,30 @@ static const struct s390_opcode s390_opcodes[] =
{ "ldeb", OP48(0xed0000000004LL), MASK_RXE_FRRD, INSTR_RXE_FRRD, 3, 0},
{ "brxlg", OP48(0xec0000000045LL), MASK_RIE_RRP, INSTR_RIE_RRP, 2, 2},
{ "brxhg", OP48(0xec0000000044LL), MASK_RIE_RRP, INSTR_RIE_RRP, 2, 2},
/* QEMU-ADD: */
{ "crj", OP48(0xec0000000076LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
{ "cgrj", OP48(0xec0000000064LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
{ "clrj", OP48(0xec0000000077LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
{ "clgrj", OP48(0xec0000000065LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
{ "cij", OP48(0xec000000007eLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
{ "cgij", OP48(0xec000000007cLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
{ "clij", OP48(0xec000000007fLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
{ "clgij", OP48(0xec000000007dLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
{ "risbg", OP48(0xec0000000055LL), MASK_RIE_RRIII, INSTR_RIE_RRIII, 3, 6},
{ "risbhg", OP48(0xec000000005dLL), MASK_RIE_RRIII, INSTR_RIE_RRIII, 3, 6},
{ "risblg", OP48(0xec0000000051LL), MASK_RIE_RRIII, INSTR_RIE_RRIII, 3, 6},
{ "rnsbg", OP48(0xec0000000054LL), MASK_RIE_RRIII, INSTR_RIE_RRIII, 3, 6},
{ "rosbg", OP48(0xec0000000056LL), MASK_RIE_RRIII, INSTR_RIE_RRIII, 3, 6},
{ "rxsbg", OP48(0xec0000000057LL), MASK_RIE_RRIII, INSTR_RIE_RRIII, 3, 6},
{ "cit", OP48(0xec0000000072LL), MASK_RIE_MRI, INSTR_RIE_MRI, 3, 6},
{ "cgit", OP48(0xec0000000070LL), MASK_RIE_MRI, INSTR_RIE_MRI, 3, 6},
{ "clfit", OP48(0xec0000000073LL), MASK_RIE_MRU, INSTR_RIE_MRU, 3, 6},
{ "clgit", OP48(0xec0000000071LL), MASK_RIE_MRU, INSTR_RIE_MRU, 3, 6},
{ "ahik", OP48(0xec00000000d8LL), MASK_RIE_RRI, INSTR_RIE_RRI, 3, 6},
{ "aghik", OP48(0xec00000000d9LL), MASK_RIE_RRI, INSTR_RIE_RRI, 3, 6},
{ "alhsik", OP48(0xec00000000daLL), MASK_RIE_RRI, INSTR_RIE_RRI, 3, 6},
{ "alghsik", OP48(0xec00000000dbLL), MASK_RIE_RRI, INSTR_RIE_RRI, 3, 6},
/* QEMU-END */
{ "tp", OP48(0xeb00000000c0LL), MASK_RSL_R0RD, INSTR_RSL_R0RD, 3, 0},
{ "stamy", OP48(0xeb000000009bLL), MASK_RSY_AARD, INSTR_RSY_AARD, 2, 3},
{ "lamy", OP48(0xeb000000009aLL), MASK_RSY_AARD, INSTR_RSY_AARD, 2, 3},
@ -985,6 +1045,20 @@ static const struct s390_opcode s390_opcodes[] =
{ "srag", OP48(0xeb000000000aLL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2},
{ "lmg", OP48(0xeb0000000004LL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 2, 3},
{ "lmg", OP48(0xeb0000000004LL), MASK_RSE_RRRD, INSTR_RSE_RRRD, 2, 2},
/* QEMU-ADD: */
{ "loc", OP48(0xeb00000000f2LL), MASK_SRY_MRRD, INSTR_RSY_MRRD, 3, 6},
{ "locg", OP48(0xeb00000000e2LL), MASK_SRY_MRRD, INSTR_RSY_MRRD, 3, 6},
{ "stoc", OP48(0xeb00000000f3LL), MASK_SRY_MRRD, INSTR_RSY_MRRD, 3, 6},
{ "stocg", OP48(0xeb00000000e3LL), MASK_SRY_MRRD, INSTR_RSY_MRRD, 3, 6},
{ "srak", OP48(0xeb00000000dcLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 6},
{ "slak", OP48(0xeb00000000ddLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 6},
{ "srlk", OP48(0xeb00000000deLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 6},
{ "sllk", OP48(0xeb00000000dfLL), MASK_RSY_RRRD, INSTR_RSY_RRRD, 3, 6},
{ "asi", OP48(0xeb000000006aLL), MASK_SIY_DRI, INSTR_SIY_DRI, 3, 6},
{ "alsi", OP48(0xeb000000006eLL), MASK_SIY_DRI, INSTR_SIY_DRI, 3, 6},
{ "agsi", OP48(0xeb000000007aLL), MASK_SIY_DRI, INSTR_SIY_DRI, 3, 6},
{ "algsi", OP48(0xeb000000007eLL), MASK_SIY_DRI, INSTR_SIY_DRI, 3, 6},
/* QEMU-END */
{ "unpka", OP8(0xeaLL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0},
{ "pka", OP8(0xe9LL), MASK_SS_L2RDRD, INSTR_SS_L2RDRD, 3, 0},
{ "mvcin", OP8(0xe8LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0},
@ -993,6 +1067,17 @@ static const struct s390_opcode s390_opcodes[] =
{ "tprot", OP16(0xe501LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0},
{ "strag", OP48(0xe50000000002LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 2, 2},
{ "lasp", OP16(0xe500LL), MASK_SSE_RDRD, INSTR_SSE_RDRD, 3, 0},
/* QEMU-ADD: */
{ "mvhhi", OP16(0xe544LL), MASK_SIL_DRI, INSTR_SIL_DRI, 3, 6},
{ "mvghi", OP16(0xe548LL), MASK_SIL_DRI, INSTR_SIL_DRI, 3, 6},
{ "mvhi", OP16(0xe54cLL), MASK_SIL_DRI, INSTR_SIL_DRI, 3, 6},
{ "chhsi", OP16(0xe554LL), MASK_SIL_DRI, INSTR_SIL_DRI, 3, 6},
{ "clhhsi", OP16(0xe555LL), MASK_SIL_DRI, INSTR_SIL_DRI, 3, 6},
{ "cghsi", OP16(0xe558LL), MASK_SIL_DRI, INSTR_SIL_DRI, 3, 6},
{ "clghsi", OP16(0xe559LL), MASK_SIL_DRI, INSTR_SIL_DRI, 3, 6},
{ "chsi", OP16(0xe55cLL), MASK_SIL_DRI, INSTR_SIL_DRI, 3, 6},
{ "clfhsi", OP16(0xe55dLL), MASK_SIL_DRI, INSTR_SIL_DRI, 3, 6},
/* QEMU-END */
{ "slb", OP48(0xe30000000099LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3},
{ "slb", OP48(0xe30000000099LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 3, 2},
{ "alc", OP48(0xe30000000098LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 3, 3},
@ -1116,6 +1201,9 @@ static const struct s390_opcode s390_opcodes[] =
{ "lrag", OP48(0xe30000000003LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 3},
{ "lrag", OP48(0xe30000000003LL), MASK_RXE_RRRD, INSTR_RXE_RRRD, 2, 2},
{ "ltg", OP48(0xe30000000002LL), MASK_RXY_RRRD, INSTR_RXY_RRRD, 2, 4},
/* QEMU-ADD: */
{ "pfd", OP48(0xe30000000036LL), MASK_RXY_URRD, INSTR_RXY_URRD, 3, 6},
/* QEMU-END */
{ "unpku", OP8(0xe2LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0},
{ "pku", OP8(0xe1LL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0},
{ "edmk", OP8(0xdfLL), MASK_SS_L0RDRD, INSTR_SS_L0RDRD, 3, 0},
@ -1135,6 +1223,32 @@ static const struct s390_opcode s390_opcodes[] =
{ "csst", OP16(0xc802LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 2, 5},
{ "ectg", OP16(0xc801LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 2, 5},
{ "mvcos", OP16(0xc800LL), MASK_SSF_RRDRD, INSTR_SSF_RRDRD, 2, 4},
/* QEMU-ADD: */
{ "exrl", OP16(0xc600ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "pfdrl", OP16(0xc602ll), MASK_RIL_UP, INSTR_RIL_UP, 3, 6},
{ "cghrl", OP16(0xc604ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "chrl", OP16(0xc605ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "clghrl", OP16(0xc606ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "clhrl", OP16(0xc607ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "cgrl", OP16(0xc608ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "clgrl", OP16(0xc60all), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "cgfrl", OP16(0xc60cll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "crl", OP16(0xc60dll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "clgfrl", OP16(0xc60ell), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "clrl", OP16(0xc60fll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "llhrl", OP16(0xc400ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "lghrl", OP16(0xc404ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "lhrl", OP16(0xc405ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "llghrl", OP16(0xc406ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "sthrl", OP16(0xc407ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "lgrl", OP16(0xc408ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "stgrl", OP16(0xc40bll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "lgfrl", OP16(0xc40cll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "lrl", OP16(0xc40dll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "llgfrl", OP16(0xc40ell), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "strl", OP16(0xc40fll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
/* QEMU-END */
{ "clfi", OP16(0xc20fLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4},
{ "clgfi", OP16(0xc20eLL), MASK_RIL_RU, INSTR_RIL_RU, 2, 4},
{ "cfi", OP16(0xc20dLL), MASK_RIL_RI, INSTR_RIL_RI, 2, 4},
@ -1265,6 +1379,29 @@ static const struct s390_opcode s390_opcodes[] =
{ "ltgr", OP16(0xb902LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2},
{ "lngr", OP16(0xb901LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2},
{ "lpgr", OP16(0xb900LL), MASK_RRE_RR, INSTR_RRE_RR, 2, 2},
/* QEMU-ADD: */
{ "crt", OP16(0xb972LL), MASK_RRF_M0RR, INSTR_RRF_M0RR, 3, 6},
{ "cgrt", OP16(0xb960LL), MASK_RRF_M0RR, INSTR_RRF_M0RR, 3, 6},
{ "clrt", OP16(0xb973LL), MASK_RRF_M0RR, INSTR_RRF_M0RR, 3, 6},
{ "clgrt", OP16(0xb961LL), MASK_RRF_M0RR, INSTR_RRF_M0RR, 3, 6},
{ "locr", OP16(0xb9f2LL), MASK_RRF_MRR, INSTR_RRF_MRR, 3, 6},
{ "locgr", OP16(0xb9e2LL), MASK_RRF_MRR, INSTR_RRF_MRR, 3, 6},
{ "popcnt", OP16(0xb9e1LL), MASK_RRE_RR, INSTR_RRE_RR, 3, 6},
{ "ngrk", OP16(0xb9e4LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "ogrk", OP16(0xb9e6LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "xgrk", OP16(0xb9e7LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "agrk", OP16(0xb9e8LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "sgrk", OP16(0xb9e9LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "algrk", OP16(0xb9eaLL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "slgrk", OP16(0xb9ebLL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "nrk", OP16(0xb9f4LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "ork", OP16(0xb9f6LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "xrk", OP16(0xb9f7LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "ark", OP16(0xb9f8LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "srk", OP16(0xb9f9LL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "alrk", OP16(0xb9faLL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
{ "slrk", OP16(0xb9fbLL), MASK_RRF_R0RR, INSTR_RRF_R0RR, 3, 6},
/* QEMU-END */
{ "lctl", OP8(0xb7LL), MASK_RS_CCRD, INSTR_RS_CCRD, 3, 0},
{ "stctl", OP8(0xb6LL), MASK_RS_CCRD, INSTR_RS_CCRD, 3, 0},
{ "rrxtr", OP16(0xb3ffLL), MASK_RRF_FFFU, INSTR_RRF_FFFU, 2, 5},
@ -1426,6 +1563,20 @@ static const struct s390_opcode s390_opcodes[] =
{ "ltebr", OP16(0xb302LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0},
{ "lnebr", OP16(0xb301LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0},
{ "lpebr", OP16(0xb300LL), MASK_RRE_FF, INSTR_RRE_FF, 3, 0},
/* QEMU-ADD: */
{ "clfebr", OP16(0xb39cLL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "clfdbr", OP16(0xb39dLL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "clfxbr", OP16(0xb39eLL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "clgebr", OP16(0xb3acLL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "clgdbr", OP16(0xb3adLL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "clgxbr", OP16(0xb3aeLL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "celfbr", OP16(0xb390LL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "cdlfbr", OP16(0xb391LL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "cxlfbr", OP16(0xb392LL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "celgbr", OP16(0xb3a0LL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "cdlgbr", OP16(0xb3a1LL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
{ "cxlgbr", OP16(0xb3a2LL), MASK_RRF_UUFF, INSTR_RRF_UUFF, 3, 6},
/* QEMU-END */
{ "trap4", OP16(0xb2ffLL), MASK_S_RD, INSTR_S_RD, 3, 0},
{ "lfas", OP16(0xb2bdLL), MASK_S_RD, INSTR_S_RD, 2, 5},
{ "srnmt", OP16(0xb2b9LL), MASK_S_RD, INSTR_S_RD, 2, 5},
@ -1774,22 +1925,6 @@ static const struct s390_opcode s390_opcodes[] =
{ "sckpf", OP16(0x0107LL), MASK_E, INSTR_E, 3, 0},
{ "upt", OP16(0x0102LL), MASK_E, INSTR_E, 3, 0},
{ "pr", OP16(0x0101LL), MASK_E, INSTR_E, 3, 0},
/* QEMU-ADD: */
{ "crj", OP48(0xec0000000076LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
{ "cgrj", OP48(0xec0000000064LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
{ "clrj", OP48(0xec0000000077LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
{ "clgrj", OP48(0xec0000000065LL), MASK_RIE_MRRP, INSTR_RIE_MRRP, 3, 6},
{ "cij", OP48(0xec000000007eLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
{ "cgij", OP48(0xec000000007cLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
{ "clij", OP48(0xec000000007fLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
{ "clgij", OP48(0xec000000007dLL), MASK_RIE_MRIP, INSTR_RIE_MRIP, 3, 6},
{ "lrl", OP16(0xc40dll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "lgrl", OP16(0xc408ll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
{ "lgfrl", OP16(0xc40cll), MASK_RIL_RP, INSTR_RIL_RP, 3, 6},
/* QEMU-END */
};
static const int s390_num_opcodes =

View File

@ -40,6 +40,7 @@
#include "cpu.h"
#include "qemu/sockets.h"
#include "sysemu/kvm.h"
#include "qemu/bitops.h"
#ifndef TARGET_CPU_MEMORY_RW_DEBUG
static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr,
@ -1535,27 +1536,34 @@ static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
}
#elif defined (TARGET_S390X)
#define NUM_CORE_REGS S390_NUM_TOTAL_REGS
#define NUM_CORE_REGS S390_NUM_REGS
static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n)
{
uint64_t val;
int cc_op;
switch (n) {
case S390_PSWM_REGNUM: GET_REGL(env->psw.mask); break;
case S390_PSWA_REGNUM: GET_REGL(env->psw.addr); break;
case S390_R0_REGNUM ... S390_R15_REGNUM:
GET_REGL(env->regs[n-S390_R0_REGNUM]); break;
case S390_A0_REGNUM ... S390_A15_REGNUM:
GET_REG32(env->aregs[n-S390_A0_REGNUM]); break;
case S390_FPC_REGNUM: GET_REG32(env->fpc); break;
case S390_F0_REGNUM ... S390_F15_REGNUM:
/* XXX */
break;
case S390_PC_REGNUM: GET_REGL(env->psw.addr); break;
case S390_CC_REGNUM:
env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst,
env->cc_vr);
GET_REG32(env->cc_op);
break;
case S390_PSWM_REGNUM:
cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr);
val = deposit64(env->psw.mask, 44, 2, cc_op);
GET_REGL(val);
break;
case S390_PSWA_REGNUM:
GET_REGL(env->psw.addr);
break;
case S390_R0_REGNUM ... S390_R15_REGNUM:
GET_REGL(env->regs[n-S390_R0_REGNUM]);
break;
case S390_A0_REGNUM ... S390_A15_REGNUM:
GET_REG32(env->aregs[n-S390_A0_REGNUM]);
break;
case S390_FPC_REGNUM:
GET_REG32(env->fpc);
break;
case S390_F0_REGNUM ... S390_F15_REGNUM:
GET_REG64(env->fregs[n-S390_F0_REGNUM].ll);
break;
}
return 0;
@ -1570,20 +1578,30 @@ static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n)
tmp32 = ldl_p(mem_buf);
switch (n) {
case S390_PSWM_REGNUM: env->psw.mask = tmpl; break;
case S390_PSWA_REGNUM: env->psw.addr = tmpl; break;
case S390_R0_REGNUM ... S390_R15_REGNUM:
env->regs[n-S390_R0_REGNUM] = tmpl; break;
case S390_A0_REGNUM ... S390_A15_REGNUM:
env->aregs[n-S390_A0_REGNUM] = tmp32; r=4; break;
case S390_FPC_REGNUM: env->fpc = tmp32; r=4; break;
case S390_F0_REGNUM ... S390_F15_REGNUM:
/* XXX */
break;
case S390_PC_REGNUM: env->psw.addr = tmpl; break;
case S390_CC_REGNUM: env->cc_op = tmp32; r=4; break;
case S390_PSWM_REGNUM:
env->psw.mask = tmpl;
env->cc_op = extract64(tmpl, 44, 2);
break;
case S390_PSWA_REGNUM:
env->psw.addr = tmpl;
break;
case S390_R0_REGNUM ... S390_R15_REGNUM:
env->regs[n-S390_R0_REGNUM] = tmpl;
break;
case S390_A0_REGNUM ... S390_A15_REGNUM:
env->aregs[n-S390_A0_REGNUM] = tmp32;
r = 4;
break;
case S390_FPC_REGNUM:
env->fpc = tmp32;
r = 4;
break;
case S390_F0_REGNUM ... S390_F15_REGNUM:
env->fregs[n-S390_F0_REGNUM].ll = tmpl;
break;
default:
return 0;
}
return r;
}
#elif defined (TARGET_LM32)

View File

@ -2938,71 +2938,115 @@ void cpu_loop(CPUAlphaState *env)
#ifdef TARGET_S390X
void cpu_loop(CPUS390XState *env)
{
int trapnr;
int trapnr, n, sig;
target_siginfo_t info;
target_ulong addr;
while (1) {
trapnr = cpu_s390x_exec (env);
trapnr = cpu_s390x_exec(env);
switch (trapnr) {
case EXCP_INTERRUPT:
/* just indicate that signals should be handled asap */
/* Just indicate that signals should be handled asap. */
break;
case EXCP_DEBUG:
{
int sig;
sig = gdb_handlesig (env, TARGET_SIGTRAP);
if (sig) {
info.si_signo = sig;
info.si_errno = 0;
info.si_code = TARGET_TRAP_BRKPT;
queue_signal(env, info.si_signo, &info);
}
}
break;
case EXCP_SVC:
{
int n = env->int_svc_code;
if (!n) {
/* syscalls > 255 */
n = env->regs[1];
}
env->psw.addr += env->int_svc_ilc;
env->regs[2] = do_syscall(env, n,
env->regs[2],
env->regs[3],
env->regs[4],
env->regs[5],
env->regs[6],
env->regs[7],
0, 0);
n = env->int_svc_code;
if (!n) {
/* syscalls > 255 */
n = env->regs[1];
}
env->psw.addr += env->int_svc_ilen;
env->regs[2] = do_syscall(env, n, env->regs[2], env->regs[3],
env->regs[4], env->regs[5],
env->regs[6], env->regs[7], 0, 0);
break;
case EXCP_DEBUG:
sig = gdb_handlesig(env, TARGET_SIGTRAP);
if (sig) {
n = TARGET_TRAP_BRKPT;
goto do_signal_pc;
}
break;
case EXCP_ADDR:
{
info.si_signo = SIGSEGV;
info.si_errno = 0;
case EXCP_PGM:
n = env->int_pgm_code;
switch (n) {
case PGM_OPERATION:
case PGM_PRIVILEGED:
sig = SIGILL;
n = TARGET_ILL_ILLOPC;
goto do_signal_pc;
case PGM_PROTECTION:
case PGM_ADDRESSING:
sig = SIGSEGV;
/* XXX: check env->error_code */
info.si_code = TARGET_SEGV_MAPERR;
info._sifields._sigfault._addr = env->__excp_addr;
queue_signal(env, info.si_signo, &info);
n = TARGET_SEGV_MAPERR;
addr = env->__excp_addr;
goto do_signal;
case PGM_EXECUTE:
case PGM_SPECIFICATION:
case PGM_SPECIAL_OP:
case PGM_OPERAND:
do_sigill_opn:
sig = SIGILL;
n = TARGET_ILL_ILLOPN;
goto do_signal_pc;
case PGM_FIXPT_OVERFLOW:
sig = SIGFPE;
n = TARGET_FPE_INTOVF;
goto do_signal_pc;
case PGM_FIXPT_DIVIDE:
sig = SIGFPE;
n = TARGET_FPE_INTDIV;
goto do_signal_pc;
case PGM_DATA:
n = (env->fpc >> 8) & 0xff;
if (n == 0xff) {
/* compare-and-trap */
goto do_sigill_opn;
} else {
/* An IEEE exception, simulated or otherwise. */
if (n & 0x80) {
n = TARGET_FPE_FLTINV;
} else if (n & 0x40) {
n = TARGET_FPE_FLTDIV;
} else if (n & 0x20) {
n = TARGET_FPE_FLTOVF;
} else if (n & 0x10) {
n = TARGET_FPE_FLTUND;
} else if (n & 0x08) {
n = TARGET_FPE_FLTRES;
} else {
/* ??? Quantum exception; BFP, DFP error. */
goto do_sigill_opn;
}
sig = SIGFPE;
goto do_signal_pc;
}
default:
fprintf(stderr, "Unhandled program exception: %#x\n", n);
cpu_dump_state(env, stderr, fprintf, 0);
exit(1);
}
break;
case EXCP_SPEC:
{
fprintf(stderr,"specification exception insn 0x%08x%04x\n", ldl(env->psw.addr), lduw(env->psw.addr + 4));
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = TARGET_ILL_ILLOPC;
info._sifields._sigfault._addr = env->__excp_addr;
queue_signal(env, info.si_signo, &info);
}
do_signal_pc:
addr = env->psw.addr;
do_signal:
info.si_signo = sig;
info.si_errno = 0;
info.si_code = n;
info._sifields._sigfault._addr = addr;
queue_signal(env, info.si_signo, &info);
break;
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
fprintf(stderr, "Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
exit (1);
exit(1);
}
process_pending_signals (env);
}

View File

@ -16,7 +16,7 @@ struct target_pt_regs {
target_psw_t psw;
abi_ulong gprs[TARGET_NUM_GPRS];
abi_ulong orig_gpr2;
unsigned short ilc;
unsigned short ilen;
unsigned short trap;
};

View File

@ -20,6 +20,7 @@
#include "cpu.h"
#include "helper.h"
#include "qemu/host-utils.h"
/* #define DEBUG_HELPER */
#ifdef DEBUG_HELPER
@ -28,8 +29,7 @@
#define HELPER_LOG(x...)
#endif
static inline uint32_t cc_calc_ltgt_32(CPUS390XState *env, int32_t src,
int32_t dst)
static uint32_t cc_calc_ltgt_32(int32_t src, int32_t dst)
{
if (src == dst) {
return 0;
@ -40,13 +40,12 @@ static inline uint32_t cc_calc_ltgt_32(CPUS390XState *env, int32_t src,
}
}
static inline uint32_t cc_calc_ltgt0_32(CPUS390XState *env, int32_t dst)
static uint32_t cc_calc_ltgt0_32(int32_t dst)
{
return cc_calc_ltgt_32(env, dst, 0);
return cc_calc_ltgt_32(dst, 0);
}
static inline uint32_t cc_calc_ltgt_64(CPUS390XState *env, int64_t src,
int64_t dst)
static uint32_t cc_calc_ltgt_64(int64_t src, int64_t dst)
{
if (src == dst) {
return 0;
@ -57,13 +56,12 @@ static inline uint32_t cc_calc_ltgt_64(CPUS390XState *env, int64_t src,
}
}
static inline uint32_t cc_calc_ltgt0_64(CPUS390XState *env, int64_t dst)
static uint32_t cc_calc_ltgt0_64(int64_t dst)
{
return cc_calc_ltgt_64(env, dst, 0);
return cc_calc_ltgt_64(dst, 0);
}
static inline uint32_t cc_calc_ltugtu_32(CPUS390XState *env, uint32_t src,
uint32_t dst)
static uint32_t cc_calc_ltugtu_32(uint32_t src, uint32_t dst)
{
if (src == dst) {
return 0;
@ -74,8 +72,7 @@ static inline uint32_t cc_calc_ltugtu_32(CPUS390XState *env, uint32_t src,
}
}
static inline uint32_t cc_calc_ltugtu_64(CPUS390XState *env, uint64_t src,
uint64_t dst)
static uint32_t cc_calc_ltugtu_64(uint64_t src, uint64_t dst)
{
if (src == dst) {
return 0;
@ -86,13 +83,11 @@ static inline uint32_t cc_calc_ltugtu_64(CPUS390XState *env, uint64_t src,
}
}
static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val,
uint32_t mask)
static uint32_t cc_calc_tm_32(uint32_t val, uint32_t mask)
{
uint16_t r = val & mask;
uint32_t r = val & mask;
HELPER_LOG("%s: val 0x%x mask 0x%x\n", __func__, val, mask);
if (r == 0 || mask == 0) {
if (r == 0) {
return 0;
} else if (r == mask) {
return 3;
@ -101,23 +96,17 @@ static inline uint32_t cc_calc_tm_32(CPUS390XState *env, uint32_t val,
}
}
/* set condition code for test under mask */
static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val,
uint32_t mask)
static uint32_t cc_calc_tm_64(uint64_t val, uint64_t mask)
{
uint16_t r = val & mask;
uint64_t r = val & mask;
HELPER_LOG("%s: val 0x%lx mask 0x%x r 0x%x\n", __func__, val, mask, r);
if (r == 0 || mask == 0) {
if (r == 0) {
return 0;
} else if (r == mask) {
return 3;
} else {
while (!(mask & 0x8000)) {
mask <<= 1;
val <<= 1;
}
if (val & 0x8000) {
int top = clz64(mask);
if ((int64_t)(val << top) < 0) {
return 2;
} else {
return 1;
@ -125,13 +114,12 @@ static inline uint32_t cc_calc_tm_64(CPUS390XState *env, uint64_t val,
}
}
static inline uint32_t cc_calc_nz(CPUS390XState *env, uint64_t dst)
static uint32_t cc_calc_nz(uint64_t dst)
{
return !!dst;
}
static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1,
int64_t a2, int64_t ar)
static uint32_t cc_calc_add_64(int64_t a1, int64_t a2, int64_t ar)
{
if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
return 3; /* overflow */
@ -146,26 +134,22 @@ static inline uint32_t cc_calc_add_64(CPUS390XState *env, int64_t a1,
}
}
static inline uint32_t cc_calc_addu_64(CPUS390XState *env, uint64_t a1,
uint64_t a2, uint64_t ar)
static uint32_t cc_calc_addu_64(uint64_t a1, uint64_t a2, uint64_t ar)
{
if (ar == 0) {
if (a1) {
return 2;
} else {
return 0;
}
} else {
if (ar < a1 || ar < a2) {
return 3;
} else {
return 1;
}
}
return (ar != 0) + 2 * (ar < a1);
}
static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1,
int64_t a2, int64_t ar)
static uint32_t cc_calc_addc_64(uint64_t a1, uint64_t a2, uint64_t ar)
{
/* Recover a2 + carry_in. */
uint64_t a2c = ar - a1;
/* Check for a2+carry_in overflow, then a1+a2c overflow. */
int carry_out = (a2c < a2) || (ar < a1);
return (ar != 0) + 2 * carry_out;
}
static uint32_t cc_calc_sub_64(int64_t a1, int64_t a2, int64_t ar)
{
if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
return 3; /* overflow */
@ -180,8 +164,7 @@ static inline uint32_t cc_calc_sub_64(CPUS390XState *env, int64_t a1,
}
}
static inline uint32_t cc_calc_subu_64(CPUS390XState *env, uint64_t a1,
uint64_t a2, uint64_t ar)
static uint32_t cc_calc_subu_64(uint64_t a1, uint64_t a2, uint64_t ar)
{
if (ar == 0) {
return 2;
@ -194,7 +177,25 @@ static inline uint32_t cc_calc_subu_64(CPUS390XState *env, uint64_t a1,
}
}
static inline uint32_t cc_calc_abs_64(CPUS390XState *env, int64_t dst)
static uint32_t cc_calc_subb_64(uint64_t a1, uint64_t a2, uint64_t ar)
{
/* We had borrow-in if normal subtraction isn't equal. */
int borrow_in = ar - (a1 - a2);
int borrow_out;
/* If a2 was ULONG_MAX, and borrow_in, then a2 is logically 65 bits,
and we must have had borrow out. */
if (borrow_in && a2 == (uint64_t)-1) {
borrow_out = 1;
} else {
a2 += borrow_in;
borrow_out = (a2 > a1);
}
return (ar != 0) + 2 * !borrow_out;
}
static uint32_t cc_calc_abs_64(int64_t dst)
{
if ((uint64_t)dst == 0x8000000000000000ULL) {
return 3;
@ -205,12 +206,12 @@ static inline uint32_t cc_calc_abs_64(CPUS390XState *env, int64_t dst)
}
}
static inline uint32_t cc_calc_nabs_64(CPUS390XState *env, int64_t dst)
static uint32_t cc_calc_nabs_64(int64_t dst)
{
return !!dst;
}
static inline uint32_t cc_calc_comp_64(CPUS390XState *env, int64_t dst)
static uint32_t cc_calc_comp_64(int64_t dst)
{
if ((uint64_t)dst == 0x8000000000000000ULL) {
return 3;
@ -224,8 +225,7 @@ static inline uint32_t cc_calc_comp_64(CPUS390XState *env, int64_t dst)
}
static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1,
int32_t a2, int32_t ar)
static uint32_t cc_calc_add_32(int32_t a1, int32_t a2, int32_t ar)
{
if ((a1 > 0 && a2 > 0 && ar < 0) || (a1 < 0 && a2 < 0 && ar > 0)) {
return 3; /* overflow */
@ -240,26 +240,22 @@ static inline uint32_t cc_calc_add_32(CPUS390XState *env, int32_t a1,
}
}
static inline uint32_t cc_calc_addu_32(CPUS390XState *env, uint32_t a1,
uint32_t a2, uint32_t ar)
static uint32_t cc_calc_addu_32(uint32_t a1, uint32_t a2, uint32_t ar)
{
if (ar == 0) {
if (a1) {
return 2;
} else {
return 0;
}
} else {
if (ar < a1 || ar < a2) {
return 3;
} else {
return 1;
}
}
return (ar != 0) + 2 * (ar < a1);
}
static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1,
int32_t a2, int32_t ar)
static uint32_t cc_calc_addc_32(uint32_t a1, uint32_t a2, uint32_t ar)
{
/* Recover a2 + carry_in. */
uint32_t a2c = ar - a1;
/* Check for a2+carry_in overflow, then a1+a2c overflow. */
int carry_out = (a2c < a2) || (ar < a1);
return (ar != 0) + 2 * carry_out;
}
static uint32_t cc_calc_sub_32(int32_t a1, int32_t a2, int32_t ar)
{
if ((a1 > 0 && a2 < 0 && ar < 0) || (a1 < 0 && a2 > 0 && ar > 0)) {
return 3; /* overflow */
@ -274,8 +270,7 @@ static inline uint32_t cc_calc_sub_32(CPUS390XState *env, int32_t a1,
}
}
static inline uint32_t cc_calc_subu_32(CPUS390XState *env, uint32_t a1,
uint32_t a2, uint32_t ar)
static uint32_t cc_calc_subu_32(uint32_t a1, uint32_t a2, uint32_t ar)
{
if (ar == 0) {
return 2;
@ -288,7 +283,25 @@ static inline uint32_t cc_calc_subu_32(CPUS390XState *env, uint32_t a1,
}
}
static inline uint32_t cc_calc_abs_32(CPUS390XState *env, int32_t dst)
static uint32_t cc_calc_subb_32(uint32_t a1, uint32_t a2, uint32_t ar)
{
/* We had borrow-in if normal subtraction isn't equal. */
int borrow_in = ar - (a1 - a2);
int borrow_out;
/* If a2 was UINT_MAX, and borrow_in, then a2 is logically 65 bits,
and we must have had borrow out. */
if (borrow_in && a2 == (uint32_t)-1) {
borrow_out = 1;
} else {
a2 += borrow_in;
borrow_out = (a2 > a1);
}
return (ar != 0) + 2 * !borrow_out;
}
static uint32_t cc_calc_abs_32(int32_t dst)
{
if ((uint32_t)dst == 0x80000000UL) {
return 3;
@ -299,12 +312,12 @@ static inline uint32_t cc_calc_abs_32(CPUS390XState *env, int32_t dst)
}
}
static inline uint32_t cc_calc_nabs_32(CPUS390XState *env, int32_t dst)
static uint32_t cc_calc_nabs_32(int32_t dst)
{
return !!dst;
}
static inline uint32_t cc_calc_comp_32(CPUS390XState *env, int32_t dst)
static uint32_t cc_calc_comp_32(int32_t dst)
{
if ((uint32_t)dst == 0x80000000UL) {
return 3;
@ -318,69 +331,80 @@ static inline uint32_t cc_calc_comp_32(CPUS390XState *env, int32_t dst)
}
/* calculate condition code for insert character under mask insn */
static inline uint32_t cc_calc_icm_32(CPUS390XState *env, uint32_t mask,
uint32_t val)
static uint32_t cc_calc_icm(uint64_t mask, uint64_t val)
{
uint32_t cc;
HELPER_LOG("%s: mask 0x%x val %d\n", __func__, mask, val);
if (mask == 0xf) {
if (!val) {
return 0;
} else if (val & 0x80000000) {
if ((val & mask) == 0) {
return 0;
} else {
int top = clz64(mask);
if ((int64_t)(val << top) < 0) {
return 1;
} else {
return 2;
}
}
if (!val || !mask) {
cc = 0;
} else {
while (mask != 1) {
mask >>= 1;
val >>= 8;
}
if (val & 0x80) {
cc = 1;
} else {
cc = 2;
}
}
return cc;
}
static inline uint32_t cc_calc_slag(CPUS390XState *env, uint64_t src,
uint64_t shift)
static uint32_t cc_calc_sla_32(uint32_t src, int shift)
{
uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
uint64_t match, r;
uint32_t mask = ((1U << shift) - 1U) << (32 - shift);
uint32_t sign = 1U << 31;
uint32_t match;
int32_t r;
/* check if the sign bit stays the same */
if (src & (1ULL << 63)) {
/* Check if the sign bit stays the same. */
if (src & sign) {
match = mask;
} else {
match = 0;
}
if ((src & mask) != match) {
/* overflow */
/* Overflow. */
return 3;
}
r = ((src << shift) & ((1ULL << 63) - 1)) | (src & (1ULL << 63));
if ((int64_t)r == 0) {
r = ((src << shift) & ~sign) | (src & sign);
if (r == 0) {
return 0;
} else if ((int64_t)r < 0) {
} else if (r < 0) {
return 1;
}
return 2;
}
static uint32_t cc_calc_sla_64(uint64_t src, int shift)
{
uint64_t mask = ((1ULL << shift) - 1ULL) << (64 - shift);
uint64_t sign = 1ULL << 63;
uint64_t match;
int64_t r;
static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
/* Check if the sign bit stays the same. */
if (src & sign) {
match = mask;
} else {
match = 0;
}
if ((src & mask) != match) {
/* Overflow. */
return 3;
}
r = ((src << shift) & ~sign) | (src & sign);
if (r == 0) {
return 0;
} else if (r < 0) {
return 1;
}
return 2;
}
static uint32_t cc_calc_flogr(uint64_t dst)
{
return dst ? 2 : 0;
}
static uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
uint64_t src, uint64_t dst, uint64_t vr)
{
uint32_t r = 0;
@ -394,95 +418,110 @@ static inline uint32_t do_calc_cc(CPUS390XState *env, uint32_t cc_op,
r = cc_op;
break;
case CC_OP_LTGT0_32:
r = cc_calc_ltgt0_32(env, dst);
r = cc_calc_ltgt0_32(dst);
break;
case CC_OP_LTGT0_64:
r = cc_calc_ltgt0_64(env, dst);
r = cc_calc_ltgt0_64(dst);
break;
case CC_OP_LTGT_32:
r = cc_calc_ltgt_32(env, src, dst);
r = cc_calc_ltgt_32(src, dst);
break;
case CC_OP_LTGT_64:
r = cc_calc_ltgt_64(env, src, dst);
r = cc_calc_ltgt_64(src, dst);
break;
case CC_OP_LTUGTU_32:
r = cc_calc_ltugtu_32(env, src, dst);
r = cc_calc_ltugtu_32(src, dst);
break;
case CC_OP_LTUGTU_64:
r = cc_calc_ltugtu_64(env, src, dst);
r = cc_calc_ltugtu_64(src, dst);
break;
case CC_OP_TM_32:
r = cc_calc_tm_32(env, src, dst);
r = cc_calc_tm_32(src, dst);
break;
case CC_OP_TM_64:
r = cc_calc_tm_64(env, src, dst);
r = cc_calc_tm_64(src, dst);
break;
case CC_OP_NZ:
r = cc_calc_nz(env, dst);
r = cc_calc_nz(dst);
break;
case CC_OP_ADD_64:
r = cc_calc_add_64(env, src, dst, vr);
r = cc_calc_add_64(src, dst, vr);
break;
case CC_OP_ADDU_64:
r = cc_calc_addu_64(env, src, dst, vr);
r = cc_calc_addu_64(src, dst, vr);
break;
case CC_OP_ADDC_64:
r = cc_calc_addc_64(src, dst, vr);
break;
case CC_OP_SUB_64:
r = cc_calc_sub_64(env, src, dst, vr);
r = cc_calc_sub_64(src, dst, vr);
break;
case CC_OP_SUBU_64:
r = cc_calc_subu_64(env, src, dst, vr);
r = cc_calc_subu_64(src, dst, vr);
break;
case CC_OP_SUBB_64:
r = cc_calc_subb_64(src, dst, vr);
break;
case CC_OP_ABS_64:
r = cc_calc_abs_64(env, dst);
r = cc_calc_abs_64(dst);
break;
case CC_OP_NABS_64:
r = cc_calc_nabs_64(env, dst);
r = cc_calc_nabs_64(dst);
break;
case CC_OP_COMP_64:
r = cc_calc_comp_64(env, dst);
r = cc_calc_comp_64(dst);
break;
case CC_OP_ADD_32:
r = cc_calc_add_32(env, src, dst, vr);
r = cc_calc_add_32(src, dst, vr);
break;
case CC_OP_ADDU_32:
r = cc_calc_addu_32(env, src, dst, vr);
r = cc_calc_addu_32(src, dst, vr);
break;
case CC_OP_ADDC_32:
r = cc_calc_addc_32(src, dst, vr);
break;
case CC_OP_SUB_32:
r = cc_calc_sub_32(env, src, dst, vr);
r = cc_calc_sub_32(src, dst, vr);
break;
case CC_OP_SUBU_32:
r = cc_calc_subu_32(env, src, dst, vr);
r = cc_calc_subu_32(src, dst, vr);
break;
case CC_OP_SUBB_32:
r = cc_calc_subb_32(src, dst, vr);
break;
case CC_OP_ABS_32:
r = cc_calc_abs_64(env, dst);
r = cc_calc_abs_32(dst);
break;
case CC_OP_NABS_32:
r = cc_calc_nabs_64(env, dst);
r = cc_calc_nabs_32(dst);
break;
case CC_OP_COMP_32:
r = cc_calc_comp_32(env, dst);
r = cc_calc_comp_32(dst);
break;
case CC_OP_ICM:
r = cc_calc_icm_32(env, src, dst);
r = cc_calc_icm(src, dst);
break;
case CC_OP_SLAG:
r = cc_calc_slag(env, src, dst);
case CC_OP_SLA_32:
r = cc_calc_sla_32(src, dst);
break;
case CC_OP_SLA_64:
r = cc_calc_sla_64(src, dst);
break;
case CC_OP_FLOGR:
r = cc_calc_flogr(dst);
break;
case CC_OP_LTGT_F32:
r = set_cc_f32(env, src, dst);
break;
case CC_OP_LTGT_F64:
r = set_cc_f64(env, src, dst);
break;
case CC_OP_NZ_F32:
r = set_cc_nz_f32(dst);
break;
case CC_OP_NZ_F64:
r = set_cc_nz_f64(dst);
break;
case CC_OP_NZ_F128:
r = set_cc_nz_f128(make_float128(src, dst));
break;
default:
cpu_abort(env, "Unknown CC operation: %s\n", cc_name(cc_op));
@ -505,18 +544,6 @@ uint32_t HELPER(calc_cc)(CPUS390XState *env, uint32_t cc_op, uint64_t src,
return do_calc_cc(env, cc_op, src, dst, vr);
}
/* insert psw mask and condition code into r1 */
void HELPER(ipm)(CPUS390XState *env, uint32_t cc, uint32_t r1)
{
uint64_t r = env->regs[r1];
r &= 0xffffffff00ffffffULL;
r |= (cc << 28) | ((env->psw.mask >> 40) & 0xf);
env->regs[r1] = r;
HELPER_LOG("%s: cc %d psw.mask 0x%lx r1 0x%lx\n", __func__,
cc, env->psw.mask, r);
}
#ifndef CONFIG_USER_ONLY
void HELPER(load_psw)(CPUS390XState *env, uint64_t mask, uint64_t addr)
{

View File

@ -60,17 +60,20 @@ typedef struct ExtQueue {
} ExtQueue;
typedef struct CPUS390XState {
uint64_t regs[16]; /* GP registers */
uint32_t aregs[16]; /* access registers */
uint32_t fpc; /* floating-point control register */
uint64_t regs[16]; /* GP registers */
CPU_DoubleU fregs[16]; /* FP registers */
uint32_t aregs[16]; /* access registers */
uint32_t fpc; /* floating-point control register */
uint32_t cc_op;
float_status fpu_status; /* passed to softfloat lib */
/* The low part of a 128-bit return, or remainder of a divide. */
uint64_t retxl;
PSW psw;
uint32_t cc_op;
uint64_t cc_src;
uint64_t cc_dst;
uint64_t cc_vr;
@ -79,15 +82,15 @@ typedef struct CPUS390XState {
uint64_t psa;
uint32_t int_pgm_code;
uint32_t int_pgm_ilc;
uint32_t int_pgm_ilen;
uint32_t int_svc_code;
uint32_t int_svc_ilc;
uint32_t int_svc_ilen;
uint64_t cregs[16]; /* control registers */
int pending_int;
ExtQueue ext_queue[MAX_EXT_QUEUE];
int pending_int;
int ext_index;
@ -113,7 +116,7 @@ static inline void cpu_clone_regs(CPUS390XState *env, target_ulong newsp)
if (newsp) {
env->regs[15] = newsp;
}
env->regs[0] = 0;
env->regs[2] = 0;
}
#endif
@ -253,25 +256,31 @@ static inline void cpu_get_tb_cpu_state(CPUS390XState* env, target_ulong *pc,
((env->psw.mask & PSW_MASK_32) ? FLAG_MASK_32 : 0);
}
static inline int get_ilc(uint8_t opc)
/* While the PoO talks about ILC (a number between 1-3) what is actually
stored in LowCore is shifted left one bit (an even between 2-6). As
this is the actual length of the insn and therefore more useful, that
is what we want to pass around and manipulate. To make sure that we
have applied this distinction universally, rename the "ILC" to "ILEN". */
static inline int get_ilen(uint8_t opc)
{
switch (opc >> 6) {
case 0:
return 1;
return 2;
case 1:
case 2:
return 2;
case 3:
return 3;
return 4;
default:
return 6;
}
return 0;
}
#define ILC_LATER 0x20
#define ILC_LATER_INC 0x21
#define ILC_LATER_INC_2 0x22
#ifndef CONFIG_USER_ONLY
/* In several cases of runtime exceptions, we havn't recorded the true
instruction length. Use these codes when raising exceptions in order
to re-compute the length by examining the insn in memory. */
#define ILEN_LATER 0x20
#define ILEN_LATER_INC 0x21
#endif
S390CPU *cpu_s390x_init(const char *cpu_model);
void s390x_translate_init(void);
@ -352,21 +361,10 @@ static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
#include "exec/exec-all.h"
#ifdef CONFIG_USER_ONLY
#define EXCP_OPEX 1 /* operation exception (sigill) */
#define EXCP_SVC 2 /* supervisor call (syscall) */
#define EXCP_ADDR 5 /* addressing exception */
#define EXCP_SPEC 6 /* specification exception */
#else
#define EXCP_EXT 1 /* external interrupt */
#define EXCP_SVC 2 /* supervisor call (syscall) */
#define EXCP_PGM 3 /* program interruption */
#endif /* CONFIG_USER_ONLY */
#define INTERRUPT_EXT (1 << 0)
#define INTERRUPT_TOD (1 << 1)
#define INTERRUPT_CPUTIMER (1 << 2)
@ -430,79 +428,6 @@ static inline void cpu_set_tls(CPUS390XState *env, target_ulong newtls)
/* Total. */
#define S390_NUM_REGS 51
/* Pseudo registers -- PC and condition code. */
#define S390_PC_REGNUM S390_NUM_REGS
#define S390_CC_REGNUM (S390_NUM_REGS+1)
#define S390_NUM_PSEUDO_REGS 2
#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
/* Program Status Word. */
#define S390_PSWM_REGNUM 0
#define S390_PSWA_REGNUM 1
/* General Purpose Registers. */
#define S390_R0_REGNUM 2
#define S390_R1_REGNUM 3
#define S390_R2_REGNUM 4
#define S390_R3_REGNUM 5
#define S390_R4_REGNUM 6
#define S390_R5_REGNUM 7
#define S390_R6_REGNUM 8
#define S390_R7_REGNUM 9
#define S390_R8_REGNUM 10
#define S390_R9_REGNUM 11
#define S390_R10_REGNUM 12
#define S390_R11_REGNUM 13
#define S390_R12_REGNUM 14
#define S390_R13_REGNUM 15
#define S390_R14_REGNUM 16
#define S390_R15_REGNUM 17
/* Access Registers. */
#define S390_A0_REGNUM 18
#define S390_A1_REGNUM 19
#define S390_A2_REGNUM 20
#define S390_A3_REGNUM 21
#define S390_A4_REGNUM 22
#define S390_A5_REGNUM 23
#define S390_A6_REGNUM 24
#define S390_A7_REGNUM 25
#define S390_A8_REGNUM 26
#define S390_A9_REGNUM 27
#define S390_A10_REGNUM 28
#define S390_A11_REGNUM 29
#define S390_A12_REGNUM 30
#define S390_A13_REGNUM 31
#define S390_A14_REGNUM 32
#define S390_A15_REGNUM 33
/* Floating Point Control Word. */
#define S390_FPC_REGNUM 34
/* Floating Point Registers. */
#define S390_F0_REGNUM 35
#define S390_F1_REGNUM 36
#define S390_F2_REGNUM 37
#define S390_F3_REGNUM 38
#define S390_F4_REGNUM 39
#define S390_F5_REGNUM 40
#define S390_F6_REGNUM 41
#define S390_F7_REGNUM 42
#define S390_F8_REGNUM 43
#define S390_F9_REGNUM 44
#define S390_F10_REGNUM 45
#define S390_F11_REGNUM 46
#define S390_F12_REGNUM 47
#define S390_F13_REGNUM 48
#define S390_F14_REGNUM 49
#define S390_F15_REGNUM 50
/* Total. */
#define S390_NUM_REGS 51
/* Pseudo registers -- PC and condition code. */
#define S390_PC_REGNUM S390_NUM_REGS
#define S390_CC_REGNUM (S390_NUM_REGS+1)
#define S390_NUM_PSEUDO_REGS 2
#define S390_NUM_TOTAL_REGS (S390_NUM_REGS+2)
/* CC optimization */
enum cc_op {
@ -524,15 +449,19 @@ enum cc_op {
CC_OP_ADD_64, /* overflow on add (64bit) */
CC_OP_ADDU_64, /* overflow on unsigned add (64bit) */
CC_OP_ADDC_64, /* overflow on unsigned add-carry (64bit) */
CC_OP_SUB_64, /* overflow on subtraction (64bit) */
CC_OP_SUBU_64, /* overflow on unsigned subtraction (64bit) */
CC_OP_SUBB_64, /* overflow on unsigned sub-borrow (64bit) */
CC_OP_ABS_64, /* sign eval on abs (64bit) */
CC_OP_NABS_64, /* sign eval on nabs (64bit) */
CC_OP_ADD_32, /* overflow on add (32bit) */
CC_OP_ADDU_32, /* overflow on unsigned add (32bit) */
CC_OP_ADDC_32, /* overflow on unsigned add-carry (32bit) */
CC_OP_SUB_32, /* overflow on subtraction (32bit) */
CC_OP_SUBU_32, /* overflow on unsigned subtraction (32bit) */
CC_OP_SUBB_32, /* overflow on unsigned sub-borrow (32bit) */
CC_OP_ABS_32, /* sign eval on abs (64bit) */
CC_OP_NABS_32, /* sign eval on nabs (64bit) */
@ -542,14 +471,14 @@ enum cc_op {
CC_OP_TM_32, /* test under mask (32bit) */
CC_OP_TM_64, /* test under mask (64bit) */
CC_OP_LTGT_F32, /* FP compare (32bit) */
CC_OP_LTGT_F64, /* FP compare (64bit) */
CC_OP_NZ_F32, /* FP dst != 0 (32bit) */
CC_OP_NZ_F64, /* FP dst != 0 (64bit) */
CC_OP_NZ_F128, /* FP dst != 0 (128bit) */
CC_OP_ICM, /* insert characters under mask */
CC_OP_SLAG, /* Calculate shift left signed */
CC_OP_SLA_32, /* Calculate shift left signed (32bit) */
CC_OP_SLA_64, /* Calculate shift left signed (64bit) */
CC_OP_FLOGR, /* find leftmost one */
CC_OP_MAX
};
@ -569,26 +498,31 @@ static const char *cc_names[] = {
[CC_OP_LTGT0_64] = "CC_OP_LTGT0_64",
[CC_OP_ADD_64] = "CC_OP_ADD_64",
[CC_OP_ADDU_64] = "CC_OP_ADDU_64",
[CC_OP_ADDC_64] = "CC_OP_ADDC_64",
[CC_OP_SUB_64] = "CC_OP_SUB_64",
[CC_OP_SUBU_64] = "CC_OP_SUBU_64",
[CC_OP_SUBB_64] = "CC_OP_SUBB_64",
[CC_OP_ABS_64] = "CC_OP_ABS_64",
[CC_OP_NABS_64] = "CC_OP_NABS_64",
[CC_OP_ADD_32] = "CC_OP_ADD_32",
[CC_OP_ADDU_32] = "CC_OP_ADDU_32",
[CC_OP_ADDC_32] = "CC_OP_ADDC_32",
[CC_OP_SUB_32] = "CC_OP_SUB_32",
[CC_OP_SUBU_32] = "CC_OP_SUBU_32",
[CC_OP_SUBB_32] = "CC_OP_SUBB_32",
[CC_OP_ABS_32] = "CC_OP_ABS_32",
[CC_OP_NABS_32] = "CC_OP_NABS_32",
[CC_OP_COMP_32] = "CC_OP_COMP_32",
[CC_OP_COMP_64] = "CC_OP_COMP_64",
[CC_OP_TM_32] = "CC_OP_TM_32",
[CC_OP_TM_64] = "CC_OP_TM_64",
[CC_OP_LTGT_F32] = "CC_OP_LTGT_F32",
[CC_OP_LTGT_F64] = "CC_OP_LTGT_F64",
[CC_OP_NZ_F32] = "CC_OP_NZ_F32",
[CC_OP_NZ_F64] = "CC_OP_NZ_F64",
[CC_OP_NZ_F128] = "CC_OP_NZ_F128",
[CC_OP_ICM] = "CC_OP_ICM",
[CC_OP_SLAG] = "CC_OP_SLAG",
[CC_OP_SLA_32] = "CC_OP_SLA_32",
[CC_OP_SLA_64] = "CC_OP_SLA_64",
[CC_OP_FLOGR] = "CC_OP_FLOGR",
};
static inline const char *cc_name(int cc_op)
@ -605,9 +539,9 @@ typedef struct LowCore
uint32_t ext_params; /* 0x080 */
uint16_t cpu_addr; /* 0x084 */
uint16_t ext_int_code; /* 0x086 */
uint16_t svc_ilc; /* 0x088 */
uint16_t svc_ilen; /* 0x088 */
uint16_t svc_code; /* 0x08a */
uint16_t pgm_ilc; /* 0x08c */
uint16_t pgm_ilen; /* 0x08c */
uint16_t pgm_code; /* 0x08e */
uint32_t data_exc_code; /* 0x090 */
uint16_t mon_class_num; /* 0x094 */
@ -991,12 +925,13 @@ static inline void cpu_pc_from_tb(CPUS390XState *env, TranslationBlock* tb)
}
/* fpu_helper.c */
uint32_t set_cc_f32(CPUS390XState *env, float32 v1, float32 v2);
uint32_t set_cc_f64(CPUS390XState *env, float64 v1, float64 v2);
uint32_t set_cc_nz_f32(float32 v);
uint32_t set_cc_nz_f64(float64 v);
uint32_t set_cc_nz_f128(float128 v);
/* misc_helper.c */
void program_interrupt(CPUS390XState *env, uint32_t code, int ilc);
void program_interrupt(CPUS390XState *env, uint32_t code, int ilen);
void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
uintptr_t retaddr);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -99,10 +99,10 @@ void do_interrupt(CPUS390XState *env)
int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong address,
int rw, int mmu_idx)
{
/* fprintf(stderr, "%s: address 0x%lx rw %d mmu_idx %d\n",
__func__, address, rw, mmu_idx); */
env->exception_index = EXCP_ADDR;
/* FIXME: find out how this works on a real machine */
env->exception_index = EXCP_PGM;
env->int_pgm_code = PGM_ADDRESSING;
/* On real machines this value is dropped into LowMem. Since this
is userland, simply put this someplace that cpu_loop can find it. */
env->__excp_addr = address;
return 1;
}
@ -111,11 +111,11 @@ int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong address,
/* Ensure to exit the TB after this call! */
static void trigger_pgm_exception(CPUS390XState *env, uint32_t code,
uint32_t ilc)
uint32_t ilen)
{
env->exception_index = EXCP_PGM;
env->int_pgm_code = code;
env->int_pgm_ilc = ilc;
env->int_pgm_ilen = ilen;
}
static int trans_bits(CPUS390XState *env, uint64_t mode)
@ -143,30 +143,30 @@ static int trans_bits(CPUS390XState *env, uint64_t mode)
static void trigger_prot_fault(CPUS390XState *env, target_ulong vaddr,
uint64_t mode)
{
int ilc = ILC_LATER_INC_2;
int ilen = ILEN_LATER_INC;
int bits = trans_bits(env, mode) | 4;
DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
trigger_pgm_exception(env, PGM_PROTECTION, ilc);
trigger_pgm_exception(env, PGM_PROTECTION, ilen);
}
static void trigger_page_fault(CPUS390XState *env, target_ulong vaddr,
uint32_t type, uint64_t asc, int rw)
{
int ilc = ILC_LATER;
int ilen = ILEN_LATER;
int bits = trans_bits(env, asc);
/* Code accesses have an undefined ilc. */
if (rw == 2) {
/* code has is undefined ilc */
ilc = 2;
ilen = 2;
}
DPRINTF("%s: vaddr=%016" PRIx64 " bits=%d\n", __func__, vaddr, bits);
stq_phys(env->psa + offsetof(LowCore, trans_exc_code), vaddr | bits);
trigger_pgm_exception(env, type, ilc);
trigger_pgm_exception(env, type, ilen);
}
static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr,
@ -406,7 +406,7 @@ int cpu_s390x_handle_mmu_fault(CPUS390XState *env, target_ulong orig_vaddr,
if (raddr > (ram_size + virtio_size)) {
DPRINTF("%s: aaddr %" PRIx64 " > ram_size %" PRIx64 "\n", __func__,
(uint64_t)aaddr, (uint64_t)ram_size);
trigger_pgm_exception(env, PGM_ADDRESSING, ILC_LATER);
trigger_pgm_exception(env, PGM_ADDRESSING, ILEN_LATER);
return 1;
}
@ -454,18 +454,19 @@ void load_psw(CPUS390XState *env, uint64_t mask, uint64_t addr)
env->psw.addr = addr;
env->psw.mask = mask;
env->cc_op = (mask >> 13) & 3;
env->cc_op = (mask >> 44) & 3;
}
static uint64_t get_psw_mask(CPUS390XState *env)
{
uint64_t r = env->psw.mask;
uint64_t r;
env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr);
r &= ~(3ULL << 13);
r = env->psw.mask;
r &= ~PSW_MASK_CC;
assert(!(env->cc_op & ~3));
r |= env->cc_op << 13;
r |= (uint64_t)env->cc_op << 44;
return r;
}
@ -479,9 +480,9 @@ static void do_svc_interrupt(CPUS390XState *env)
lowcore = cpu_physical_memory_map(env->psa, &len, 1);
lowcore->svc_code = cpu_to_be16(env->int_svc_code);
lowcore->svc_ilc = cpu_to_be16(env->int_svc_ilc);
lowcore->svc_ilen = cpu_to_be16(env->int_svc_ilen);
lowcore->svc_old_psw.mask = cpu_to_be64(get_psw_mask(env));
lowcore->svc_old_psw.addr = cpu_to_be64(env->psw.addr + (env->int_svc_ilc));
lowcore->svc_old_psw.addr = cpu_to_be64(env->psw.addr + env->int_svc_ilen);
mask = be64_to_cpu(lowcore->svc_new_psw.mask);
addr = be64_to_cpu(lowcore->svc_new_psw.addr);
@ -495,28 +496,26 @@ static void do_program_interrupt(CPUS390XState *env)
uint64_t mask, addr;
LowCore *lowcore;
hwaddr len = TARGET_PAGE_SIZE;
int ilc = env->int_pgm_ilc;
int ilen = env->int_pgm_ilen;
switch (ilc) {
case ILC_LATER:
ilc = get_ilc(cpu_ldub_code(env, env->psw.addr));
switch (ilen) {
case ILEN_LATER:
ilen = get_ilen(cpu_ldub_code(env, env->psw.addr));
break;
case ILC_LATER_INC:
ilc = get_ilc(cpu_ldub_code(env, env->psw.addr));
env->psw.addr += ilc * 2;
break;
case ILC_LATER_INC_2:
ilc = get_ilc(cpu_ldub_code(env, env->psw.addr)) * 2;
env->psw.addr += ilc;
case ILEN_LATER_INC:
ilen = get_ilen(cpu_ldub_code(env, env->psw.addr));
env->psw.addr += ilen;
break;
default:
assert(ilen == 2 || ilen == 4 || ilen == 6);
}
qemu_log_mask(CPU_LOG_INT, "%s: code=0x%x ilc=%d\n",
__func__, env->int_pgm_code, ilc);
qemu_log_mask(CPU_LOG_INT, "%s: code=0x%x ilen=%d\n",
__func__, env->int_pgm_code, ilen);
lowcore = cpu_physical_memory_map(env->psa, &len, 1);
lowcore->pgm_ilc = cpu_to_be16(ilc);
lowcore->pgm_ilen = cpu_to_be16(ilen);
lowcore->pgm_code = cpu_to_be16(env->int_pgm_code);
lowcore->program_old_psw.mask = cpu_to_be64(get_psw_mask(env));
lowcore->program_old_psw.addr = cpu_to_be64(env->psw.addr);
@ -526,7 +525,7 @@ static void do_program_interrupt(CPUS390XState *env)
cpu_physical_memory_unmap(lowcore, len, 1, len);
DPRINTF("%s: %x %x %" PRIx64 " %" PRIx64 "\n", __func__,
env->int_pgm_code, ilc, env->psw.mask,
env->int_pgm_code, ilen, env->psw.mask,
env->psw.addr);
load_psw(env, mask, addr);

View File

@ -1,152 +1,120 @@
#include "exec/def-helper.h"
DEF_HELPER_2(exception, void, env, i32)
DEF_HELPER_4(nc, i32, env, i32, i64, i64)
DEF_HELPER_4(oc, i32, env, i32, i64, i64)
DEF_HELPER_4(xc, i32, env, i32, i64, i64)
DEF_HELPER_4(mvc, void, env, i32, i64, i64)
DEF_HELPER_4(clc, i32, env, i32, i64, i64)
DEF_HELPER_2(exception, noreturn, env, i32)
DEF_HELPER_FLAGS_4(nc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(oc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(xc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(mvc, TCG_CALL_NO_WG, void, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(clc, TCG_CALL_NO_WG, i32, env, i32, i64, i64)
DEF_HELPER_3(mvcl, i32, env, i32, i32)
DEF_HELPER_FLAGS_1(set_cc_comp_s32, TCG_CALL_NO_RWG_SE, i32, s32)
DEF_HELPER_FLAGS_1(set_cc_comp_s64, TCG_CALL_NO_RWG_SE, i32, s64)
DEF_HELPER_FLAGS_2(set_cc_icm, TCG_CALL_NO_RWG_SE, i32, i32, i32)
DEF_HELPER_4(clm, i32, env, i32, i32, i64)
DEF_HELPER_4(stcm, void, env, i32, i32, i64)
DEF_HELPER_3(mlg, void, env, i32, i64)
DEF_HELPER_3(dlg, void, env, i32, i64)
DEF_HELPER_FLAGS_3(set_cc_add64, TCG_CALL_NO_RWG_SE, i32, s64, s64, s64)
DEF_HELPER_FLAGS_3(set_cc_addu64, TCG_CALL_NO_RWG_SE, i32, i64, i64, i64)
DEF_HELPER_FLAGS_3(set_cc_add32, TCG_CALL_NO_RWG_SE, i32, s32, s32, s32)
DEF_HELPER_FLAGS_3(set_cc_addu32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
DEF_HELPER_FLAGS_3(set_cc_sub64, TCG_CALL_NO_RWG_SE, i32, s64, s64, s64)
DEF_HELPER_FLAGS_3(set_cc_subu64, TCG_CALL_NO_RWG_SE, i32, i64, i64, i64)
DEF_HELPER_FLAGS_3(set_cc_sub32, TCG_CALL_NO_RWG_SE, i32, s32, s32, s32)
DEF_HELPER_FLAGS_3(set_cc_subu32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
DEF_HELPER_4(srst, i32, env, i32, i32, i32)
DEF_HELPER_4(clst, i32, env, i32, i32, i32)
DEF_HELPER_FLAGS_4(clm, TCG_CALL_NO_WG, i32, env, i32, i32, i64)
DEF_HELPER_FLAGS_3(mul128, TCG_CALL_NO_RWG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(divs32, TCG_CALL_NO_WG, s64, env, s64, s64)
DEF_HELPER_FLAGS_3(divu32, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(divs64, TCG_CALL_NO_WG, s64, env, s64, s64)
DEF_HELPER_FLAGS_4(divu64, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_4(srst, i64, env, i64, i64, i64)
DEF_HELPER_4(clst, i64, env, i64, i64, i64)
DEF_HELPER_4(mvpg, void, env, i64, i64, i64)
DEF_HELPER_4(mvst, void, env, i32, i32, i32)
DEF_HELPER_4(csg, i32, env, i32, i64, i32)
DEF_HELPER_4(cdsg, i32, env, i32, i64, i32)
DEF_HELPER_4(cs, i32, env, i32, i64, i32)
DEF_HELPER_4(mvst, i64, env, i64, i64, i64)
DEF_HELPER_5(ex, i32, env, i32, i64, i64, i64)
DEF_HELPER_FLAGS_1(abs_i32, TCG_CALL_NO_RWG_SE, i32, s32)
DEF_HELPER_FLAGS_1(nabs_i32, TCG_CALL_NO_RWG_SE, s32, s32)
DEF_HELPER_FLAGS_1(abs_i64, TCG_CALL_NO_RWG_SE, i64, s64)
DEF_HELPER_FLAGS_1(nabs_i64, TCG_CALL_NO_RWG_SE, s64, s64)
DEF_HELPER_4(stcmh, void, env, i32, i64, i32)
DEF_HELPER_4(icmh, i32, env, i32, i64, i32)
DEF_HELPER_3(ipm, void, env, i32, i32)
DEF_HELPER_FLAGS_3(addc_u32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
DEF_HELPER_FLAGS_3(set_cc_addc_u64, TCG_CALL_NO_RWG_SE, i32, i64, i64, i64)
DEF_HELPER_4(stam, void, env, i32, i64, i32)
DEF_HELPER_4(lam, void, env, i32, i64, i32)
DEF_HELPER_FLAGS_4(stam, TCG_CALL_NO_WG, void, env, i32, i64, i32)
DEF_HELPER_FLAGS_4(lam, TCG_CALL_NO_WG, void, env, i32, i64, i32)
DEF_HELPER_4(mvcle, i32, env, i32, i64, i32)
DEF_HELPER_4(clcle, i32, env, i32, i64, i32)
DEF_HELPER_4(slb, i32, env, i32, i32, i32)
DEF_HELPER_5(slbg, i32, env, i32, i32, i64, i64)
DEF_HELPER_3(cefbr, void, env, i32, s32)
DEF_HELPER_3(cdfbr, void, env, i32, s32)
DEF_HELPER_3(cxfbr, void, env, i32, s32)
DEF_HELPER_3(cegbr, void, env, i32, s64)
DEF_HELPER_3(cdgbr, void, env, i32, s64)
DEF_HELPER_3(cxgbr, void, env, i32, s64)
DEF_HELPER_3(adbr, i32, env, i32, i32)
DEF_HELPER_3(aebr, i32, env, i32, i32)
DEF_HELPER_3(sebr, i32, env, i32, i32)
DEF_HELPER_3(sdbr, i32, env, i32, i32)
DEF_HELPER_3(debr, void, env, i32, i32)
DEF_HELPER_3(dxbr, void, env, i32, i32)
DEF_HELPER_3(mdbr, void, env, i32, i32)
DEF_HELPER_3(mxbr, void, env, i32, i32)
DEF_HELPER_3(ldebr, void, env, i32, i32)
DEF_HELPER_3(ldxbr, void, env, i32, i32)
DEF_HELPER_3(lxdbr, void, env, i32, i32)
DEF_HELPER_3(ledbr, void, env, i32, i32)
DEF_HELPER_3(lexbr, void, env, i32, i32)
DEF_HELPER_3(lpebr, i32, env, i32, i32)
DEF_HELPER_3(lpdbr, i32, env, i32, i32)
DEF_HELPER_3(lpxbr, i32, env, i32, i32)
DEF_HELPER_3(ltebr, i32, env, i32, i32)
DEF_HELPER_3(ltdbr, i32, env, i32, i32)
DEF_HELPER_3(ltxbr, i32, env, i32, i32)
DEF_HELPER_3(lcebr, i32, env, i32, i32)
DEF_HELPER_3(lcdbr, i32, env, i32, i32)
DEF_HELPER_3(lcxbr, i32, env, i32, i32)
DEF_HELPER_3(aeb, void, env, i32, i32)
DEF_HELPER_3(deb, void, env, i32, i32)
DEF_HELPER_3(meeb, void, env, i32, i32)
DEF_HELPER_3(cdb, i32, env, i32, i64)
DEF_HELPER_3(adb, i32, env, i32, i64)
DEF_HELPER_3(seb, void, env, i32, i32)
DEF_HELPER_3(sdb, i32, env, i32, i64)
DEF_HELPER_3(mdb, void, env, i32, i64)
DEF_HELPER_3(ddb, void, env, i32, i64)
DEF_HELPER_FLAGS_3(cebr, TCG_CALL_NO_SE, i32, env, i32, i32)
DEF_HELPER_FLAGS_3(cdbr, TCG_CALL_NO_SE, i32, env, i32, i32)
DEF_HELPER_FLAGS_3(cxbr, TCG_CALL_NO_SE, i32, env, i32, i32)
DEF_HELPER_4(cgebr, i32, env, i32, i32, i32)
DEF_HELPER_4(cgdbr, i32, env, i32, i32, i32)
DEF_HELPER_4(cgxbr, i32, env, i32, i32, i32)
DEF_HELPER_2(lzer, void, env, i32)
DEF_HELPER_2(lzdr, void, env, i32)
DEF_HELPER_2(lzxr, void, env, i32)
DEF_HELPER_4(cfebr, i32, env, i32, i32, i32)
DEF_HELPER_4(cfdbr, i32, env, i32, i32, i32)
DEF_HELPER_4(cfxbr, i32, env, i32, i32, i32)
DEF_HELPER_3(axbr, i32, env, i32, i32)
DEF_HELPER_3(sxbr, i32, env, i32, i32)
DEF_HELPER_3(meebr, void, env, i32, i32)
DEF_HELPER_3(ddbr, void, env, i32, i32)
DEF_HELPER_4(madb, void, env, i32, i64, i32)
DEF_HELPER_4(maebr, void, env, i32, i32, i32)
DEF_HELPER_4(madbr, void, env, i32, i32, i32)
DEF_HELPER_4(msdbr, void, env, i32, i32, i32)
DEF_HELPER_3(ldeb, void, env, i32, i64)
DEF_HELPER_3(lxdb, void, env, i32, i64)
DEF_HELPER_FLAGS_3(tceb, TCG_CALL_NO_SE, i32, env, i32, i64)
DEF_HELPER_FLAGS_3(tcdb, TCG_CALL_NO_SE, i32, env, i32, i64)
DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_NO_SE, i32, env, i32, i64)
DEF_HELPER_3(flogr, i32, env, i32, i64)
DEF_HELPER_3(sqdbr, void, env, i32, i32)
DEF_HELPER_3(cegb, i64, env, s64, i32)
DEF_HELPER_3(cdgb, i64, env, s64, i32)
DEF_HELPER_3(cxgb, i64, env, s64, i32)
DEF_HELPER_3(celgb, i64, env, i64, i32)
DEF_HELPER_3(cdlgb, i64, env, i64, i32)
DEF_HELPER_3(cxlgb, i64, env, i64, i32)
DEF_HELPER_FLAGS_3(aeb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(adb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_5(axb, TCG_CALL_NO_WG, i64, env, i64, i64, i64, i64)
DEF_HELPER_FLAGS_3(seb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(sdb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_5(sxb, TCG_CALL_NO_WG, i64, env, i64, i64, i64, i64)
DEF_HELPER_FLAGS_3(deb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(ddb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_5(dxb, TCG_CALL_NO_WG, i64, env, i64, i64, i64, i64)
DEF_HELPER_FLAGS_3(meeb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(mdeb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(mdb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_5(mxb, TCG_CALL_NO_WG, i64, env, i64, i64, i64, i64)
DEF_HELPER_FLAGS_4(mxdb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_2(ldeb, TCG_CALL_NO_WG, i64, env, i64)
DEF_HELPER_FLAGS_3(ldxb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_2(lxdb, TCG_CALL_NO_WG, i64, env, i64)
DEF_HELPER_FLAGS_2(lxeb, TCG_CALL_NO_WG, i64, env, i64)
DEF_HELPER_FLAGS_2(ledb, TCG_CALL_NO_WG, i64, env, i64)
DEF_HELPER_FLAGS_3(lexb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_3(ceb, TCG_CALL_NO_WG_SE, i32, env, i64, i64)
DEF_HELPER_FLAGS_3(cdb, TCG_CALL_NO_WG_SE, i32, env, i64, i64)
DEF_HELPER_FLAGS_5(cxb, TCG_CALL_NO_WG_SE, i32, env, i64, i64, i64, i64)
DEF_HELPER_FLAGS_3(cgeb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_3(cgdb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_4(cgxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32)
DEF_HELPER_FLAGS_3(cfeb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_3(cfdb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_4(cfxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32)
DEF_HELPER_FLAGS_3(clgeb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_3(clgdb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_4(clgxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32)
DEF_HELPER_FLAGS_3(clfeb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_3(clfdb, TCG_CALL_NO_WG, i64, env, i64, i32)
DEF_HELPER_FLAGS_4(clfxb, TCG_CALL_NO_WG, i64, env, i64, i64, i32)
DEF_HELPER_FLAGS_4(maeb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(madb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(mseb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(msdb, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_2(tceb, TCG_CALL_NO_RWG_SE, i32, i64, i64)
DEF_HELPER_FLAGS_2(tcdb, TCG_CALL_NO_RWG_SE, i32, i64, i64)
DEF_HELPER_FLAGS_3(tcxb, TCG_CALL_NO_RWG_SE, i32, i64, i64, i64)
DEF_HELPER_FLAGS_1(clz, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_2(sqeb, TCG_CALL_NO_WG, i64, env, i64)
DEF_HELPER_FLAGS_2(sqdb, TCG_CALL_NO_WG, i64, env, i64)
DEF_HELPER_FLAGS_3(sqxb, TCG_CALL_NO_WG, i64, env, i64, i64)
DEF_HELPER_FLAGS_1(cvd, TCG_CALL_NO_RWG_SE, i64, s32)
DEF_HELPER_4(unpk, void, env, i32, i64, i64)
DEF_HELPER_4(tr, void, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(unpk, TCG_CALL_NO_WG, void, env, i32, i64, i64)
DEF_HELPER_FLAGS_4(tr, TCG_CALL_NO_WG, void, env, i32, i64, i64)
DEF_HELPER_4(cksm, i64, env, i64, i64, i64)
DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_NO_RWG_SE, i32, env, i32, i64, i64, i64)
DEF_HELPER_FLAGS_2(sfpc, TCG_CALL_NO_RWG, void, env, i64)
DEF_HELPER_FLAGS_2(sfas, TCG_CALL_NO_WG, void, env, i64)
DEF_HELPER_FLAGS_1(popcnt, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_3(servc, i32, env, i32, i64)
#ifndef CONFIG_USER_ONLY
DEF_HELPER_3(servc, i32, env, i64, i64)
DEF_HELPER_4(diag, i64, env, i32, i64, i64)
DEF_HELPER_3(load_psw, void, env, i64, i64)
DEF_HELPER_1(program_interrupt, void, i32)
DEF_HELPER_FLAGS_2(stidp, TCG_CALL_NO_RWG, void, env, i64)
DEF_HELPER_3(load_psw, noreturn, env, i64, i64)
DEF_HELPER_FLAGS_2(spx, TCG_CALL_NO_RWG, void, env, i64)
DEF_HELPER_FLAGS_1(sck, TCG_CALL_NO_RWG, i32, i64)
DEF_HELPER_2(stck, i32, env, i64)
DEF_HELPER_2(stcke, i32, env, i64)
DEF_HELPER_FLAGS_1(stck, TCG_CALL_NO_RWG_SE, i64, env)
DEF_HELPER_FLAGS_2(sckc, TCG_CALL_NO_RWG, void, env, i64)
DEF_HELPER_FLAGS_2(stckc, TCG_CALL_NO_RWG, void, env, i64)
DEF_HELPER_FLAGS_1(stckc, TCG_CALL_NO_RWG, i64, env)
DEF_HELPER_FLAGS_2(spt, TCG_CALL_NO_RWG, void, env, i64)
DEF_HELPER_FLAGS_2(stpt, TCG_CALL_NO_RWG, void, env, i64)
DEF_HELPER_4(stsi, i32, env, i64, i32, i32)
DEF_HELPER_4(lctl, void, env, i32, i64, i32)
DEF_HELPER_4(lctlg, void, env, i32, i64, i32)
DEF_HELPER_4(stctl, void, env, i32, i64, i32)
DEF_HELPER_4(stctg, void, env, i32, i64, i32)
DEF_HELPER_FLAGS_1(stpt, TCG_CALL_NO_RWG, i64, env)
DEF_HELPER_4(stsi, i32, env, i64, i64, i64)
DEF_HELPER_FLAGS_4(lctl, TCG_CALL_NO_WG, void, env, i32, i64, i32)
DEF_HELPER_FLAGS_4(lctlg, TCG_CALL_NO_WG, void, env, i32, i64, i32)
DEF_HELPER_FLAGS_4(stctl, TCG_CALL_NO_WG, void, env, i32, i64, i32)
DEF_HELPER_FLAGS_4(stctg, TCG_CALL_NO_WG, void, env, i32, i64, i32)
DEF_HELPER_FLAGS_2(tprot, TCG_CALL_NO_RWG, i32, i64, i64)
DEF_HELPER_FLAGS_2(iske, TCG_CALL_NO_RWG_SE, i64, env, i64)
DEF_HELPER_FLAGS_3(sske, TCG_CALL_NO_RWG, void, env, i32, i64)
DEF_HELPER_FLAGS_3(rrbe, TCG_CALL_NO_RWG, i32, env, i32, i64)
DEF_HELPER_3(csp, i32, env, i32, i32)
DEF_HELPER_FLAGS_3(sske, TCG_CALL_NO_RWG, void, env, i64, i64)
DEF_HELPER_FLAGS_2(rrbe, TCG_CALL_NO_RWG, i32, env, i64)
DEF_HELPER_3(csp, i32, env, i32, i64)
DEF_HELPER_4(mvcs, i32, env, i64, i64, i64)
DEF_HELPER_4(mvcp, i32, env, i64, i64, i64)
DEF_HELPER_4(sigp, i32, env, i64, i32, i64)
DEF_HELPER_2(sacf, void, env, i64)
DEF_HELPER_FLAGS_2(sacf, TCG_CALL_NO_WG, void, env, i64)
DEF_HELPER_FLAGS_3(ipte, TCG_CALL_NO_RWG, void, env, i64, i64)
DEF_HELPER_FLAGS_1(ptlb, TCG_CALL_NO_RWG, void, env)
DEF_HELPER_3(lra, i32, env, i64, i32)
DEF_HELPER_3(stura, void, env, i64, i32)
DEF_HELPER_3(cksm, void, env, i32, i32)
DEF_HELPER_FLAGS_5(calc_cc, TCG_CALL_NO_RWG_SE,
i32, env, i32, i64, i64, i64)
DEF_HELPER_2(lra, i64, env, i64)
DEF_HELPER_FLAGS_3(stura, TCG_CALL_NO_WG, void, env, i64, i64)
#endif
#include "exec/def-helper.h"

813
target-s390x/insn-data.def Normal file
View File

@ -0,0 +1,813 @@
/* ADD */
C(0x1a00, AR, RR_a, Z, r1, r2, new, r1_32, add, adds32)
C(0xb9f8, ARK, RRF_a, DO, r2, r3, new, r1_32, add, adds32)
C(0x5a00, A, RX_a, Z, r1, m2_32s, new, r1_32, add, adds32)
C(0xe35a, AY, RXY_a, LD, r1, m2_32s, new, r1_32, add, adds32)
C(0xb908, AGR, RRE, Z, r1, r2, r1, 0, add, adds64)
C(0xb918, AGFR, RRE, Z, r1, r2_32s, r1, 0, add, adds64)
C(0xb9e8, AGRK, RRF_a, DO, r2, r3, r1, 0, add, adds64)
C(0xe308, AG, RXY_a, Z, r1, m2_64, r1, 0, add, adds64)
C(0xe318, AGF, RXY_a, Z, r1, m2_32s, r1, 0, add, adds64)
C(0xb30a, AEBR, RRE, Z, e1, e2, new, e1, aeb, f32)
C(0xb31a, ADBR, RRE, Z, f1_o, f2_o, f1, 0, adb, f64)
C(0xb34a, AXBR, RRE, Z, 0, x2_o, x1, 0, axb, f128)
C(0xed0a, AEB, RXE, Z, e1, m2_32u, new, e1, aeb, f32)
C(0xed1a, ADB, RXE, Z, f1_o, m2_64, f1, 0, adb, f64)
/* ADD IMMEDIATE */
C(0xc209, AFI, RIL_a, EI, r1, i2, new, r1_32, add, adds32)
C(0xeb6a, ASI, SIY, GIE, m1_32s, i2, new, m1_32, add, adds32)
C(0xecd8, AHIK, RIE_d, DO, r3, i2, new, r1_32, add, adds32)
C(0xc208, AGFI, RIL_a, EI, r1, i2, r1, 0, add, adds64)
C(0xeb7a, AGSI, SIY, GIE, m1_64, i2, new, m1_64, add, adds64)
C(0xecd9, AGHIK, RIE_d, DO, r3, i2, r1, 0, add, adds64)
/* ADD HALFWORD */
C(0x4a00, AH, RX_a, Z, r1, m2_16s, new, r1_32, add, adds32)
C(0xe37a, AHY, RXY_a, LD, r1, m2_16s, new, r1_32, add, adds32)
/* ADD HALFWORD IMMEDIATE */
C(0xa70a, AHI, RI_a, Z, r1, i2, new, r1_32, add, adds32)
C(0xa70b, AGHI, RI_a, Z, r1, i2, r1, 0, add, adds64)
/* ADD LOGICAL */
C(0x1e00, ALR, RR_a, Z, r1, r2, new, r1_32, add, addu32)
C(0xb9fa, ALRK, RRF_a, DO, r2, r3, new, r1_32, add, addu32)
C(0x5e00, AL, RX_a, Z, r1, m2_32u, new, r1_32, add, addu32)
C(0xe35e, ALY, RXY_a, LD, r1, m2_32u, new, r1_32, add, addu32)
C(0xb90a, ALGR, RRE, Z, r1, r2, r1, 0, add, addu64)
C(0xb91a, ALGFR, RRE, Z, r1, r2_32u, r1, 0, add, addu64)
C(0xb9ea, ALGRK, RRF_a, DO, r2, r3, r1, 0, add, addu64)
C(0xe30a, ALG, RXY_a, Z, r1, m2_64, r1, 0, add, addu64)
C(0xe31a, ALGF, RXY_a, Z, r1, m2_32u, r1, 0, add, addu64)
/* ADD LOGICAL IMMEDIATE */
C(0xc20b, ALFI, RIL_a, EI, r1, i2_32u, new, r1_32, add, addu32)
C(0xc20a, ALGFI, RIL_a, EI, r1, i2_32u, r1, 0, add, addu64)
/* ADD LOGICAL WITH SIGNED IMMEDIATE */
C(0xeb6e, ALSI, SIY, GIE, m1_32u, i2, new, m1_32, add, addu32)
C(0xecda, ALHSIK, RIE_d, DO, r3, i2, new, r1_32, add, addu32)
C(0xeb7e, ALGSI, SIY, GIE, m1_64, i2, new, m1_64, add, addu64)
C(0xecdb, ALGHSIK, RIE_d, DO, r3, i2, r1, 0, add, addu64)
/* ADD LOGICAL WITH CARRY */
C(0xb998, ALCR, RRE, Z, r1, r2, new, r1_32, addc, addc32)
C(0xb988, ALCGR, RRE, Z, r1, r2, r1, 0, addc, addc64)
C(0xe398, ALC, RXY_a, Z, r1, m2_32u, new, r1_32, addc, addc32)
C(0xe388, ALCG, RXY_a, Z, r1, m2_64, r1, 0, addc, addc64)
/* AND */
C(0x1400, NR, RR_a, Z, r1, r2, new, r1_32, and, nz32)
C(0xb9f4, NRK, RRF_a, DO, r2, r3, new, r1_32, and, nz32)
C(0x5400, N, RX_a, Z, r1, m2_32s, new, r1_32, and, nz32)
C(0xe354, NY, RXY_a, LD, r1, m2_32s, new, r1_32, and, nz32)
C(0xb980, NGR, RRE, Z, r1, r2, r1, 0, and, nz64)
C(0xb9e4, NGRK, RRF_a, DO, r2, r3, r1, 0, and, nz64)
C(0xe380, NG, RXY_a, Z, r1, m2_64, r1, 0, and, nz64)
C(0xd400, NC, SS_a, Z, la1, a2, 0, 0, nc, 0)
/* AND IMMEDIATE */
D(0xc00a, NIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, andi, 0, 0x2020)
D(0xc00b, NILF, RIL_a, EI, r1_o, i2_32u, r1, 0, andi, 0, 0x2000)
D(0xa504, NIHH, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1030)
D(0xa505, NIHL, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1020)
D(0xa506, NILH, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1010)
D(0xa507, NILL, RI_a, Z, r1_o, i2_16u, r1, 0, andi, 0, 0x1000)
C(0x9400, NI, SI, Z, m1_8u, i2_8u, new, m1_8, and, nz64)
C(0xeb54, NIY, SIY, LD, m1_8u, i2_8u, new, m1_8, and, nz64)
/* BRANCH AND SAVE */
C(0x0d00, BASR, RR_a, Z, 0, r2_nz, r1, 0, bas, 0)
C(0x4d00, BAS, RX_a, Z, 0, a2, r1, 0, bas, 0)
/* BRANCH RELATIVE AND SAVE */
C(0xa705, BRAS, RI_b, Z, 0, 0, r1, 0, basi, 0)
C(0xc005, BRASL, RIL_b, Z, 0, 0, r1, 0, basi, 0)
/* BRANCH ON CONDITION */
C(0x0700, BCR, RR_b, Z, 0, r2_nz, 0, 0, bc, 0)
C(0x4700, BC, RX_b, Z, 0, a2, 0, 0, bc, 0)
/* BRANCH RELATIVE ON CONDITION */
C(0xa704, BRC, RI_c, Z, 0, 0, 0, 0, bc, 0)
C(0xc004, BRCL, RIL_c, Z, 0, 0, 0, 0, bc, 0)
/* BRANCH ON COUNT */
C(0x0600, BCTR, RR_a, Z, 0, r2_nz, 0, 0, bct32, 0)
C(0xb946, BCTGR, RRE, Z, 0, r2_nz, 0, 0, bct64, 0)
C(0x4600, BCT, RX_a, Z, 0, a2, 0, 0, bct32, 0)
C(0xe346, BCTG, RXY_a, Z, 0, a2, 0, 0, bct64, 0)
/* BRANCH RELATIVE ON COUNT */
C(0xa706, BRCT, RI_b, Z, 0, 0, 0, 0, bct32, 0)
C(0xa707, BRCTG, RI_b, Z, 0, 0, 0, 0, bct64, 0)
/* BRANCH ON INDEX */
D(0x8600, BXH, RS_a, Z, 0, a2, 0, 0, bx32, 0, 0)
D(0x8700, BXLE, RS_a, Z, 0, a2, 0, 0, bx32, 0, 1)
D(0xeb44, BXHG, RSY_a, Z, 0, a2, 0, 0, bx64, 0, 0)
D(0xeb45, BXLEG, RSY_a, Z, 0, a2, 0, 0, bx64, 0, 1)
/* BRANCH RELATIVE ON INDEX */
D(0x8400, BRXH, RSI, Z, 0, 0, 0, 0, bx32, 0, 0)
D(0x8500, BRXLE, RSI, Z, 0, 0, 0, 0, bx32, 0, 1)
D(0xec44, BRXHG, RIE_e, Z, 0, 0, 0, 0, bx64, 0, 0)
D(0xec45, BRXHLE, RIE_e, Z, 0, 0, 0, 0, bx64, 0, 1)
/* CHECKSUM */
C(0xb241, CKSM, RRE, Z, r1_o, ra2, new, r1_32, cksm, 0)
/* COPY SIGN */
C(0xb372, CPSDR, RRF_b, FPSSH, f3_o, f2_o, f1, 0, cps, 0)
/* COMPARE */
C(0x1900, CR, RR_a, Z, r1_o, r2_o, 0, 0, 0, cmps32)
C(0x5900, C, RX_a, Z, r1_o, m2_32s, 0, 0, 0, cmps32)
C(0xe359, CY, RXY_a, LD, r1_o, m2_32s, 0, 0, 0, cmps32)
C(0xb920, CGR, RRE, Z, r1_o, r2_o, 0, 0, 0, cmps64)
C(0xb930, CGFR, RRE, Z, r1_o, r2_32s, 0, 0, 0, cmps64)
C(0xe320, CG, RXY_a, Z, r1_o, m2_64, 0, 0, 0, cmps64)
C(0xe330, CGF, RXY_a, Z, r1_o, m2_32s, 0, 0, 0, cmps64)
C(0xb309, CEBR, RRE, Z, e1, e2, 0, 0, ceb, 0)
C(0xb319, CDBR, RRE, Z, f1_o, f2_o, 0, 0, cdb, 0)
C(0xb349, CXBR, RRE, Z, x1_o, x2_o, 0, 0, cxb, 0)
C(0xed09, CEB, RXE, Z, e1, m2_32u, 0, 0, ceb, 0)
C(0xed19, CDB, RXE, Z, f1_o, m2_64, 0, 0, cdb, 0)
/* COMPARE IMMEDIATE */
C(0xc20d, CFI, RIL_a, EI, r1, i2, 0, 0, 0, cmps32)
C(0xc20c, CGFI, RIL_a, EI, r1, i2, 0, 0, 0, cmps64)
/* COMPARE RELATIVE LONG */
C(0xc60d, CRL, RIL_b, GIE, r1, mri2_32s, 0, 0, 0, cmps32)
C(0xc608, CGRL, RIL_b, GIE, r1, mri2_64, 0, 0, 0, cmps64)
C(0xc60c, CGFRL, RIL_b, GIE, r1, mri2_32s, 0, 0, 0, cmps64)
/* COMPARE HALFWORD */
C(0x4900, CH, RX_a, Z, r1_o, m2_16s, 0, 0, 0, cmps32)
C(0xe379, CHY, RXY_a, LD, r1_o, m2_16s, 0, 0, 0, cmps32)
C(0xe334, CGH, RXY_a, GIE, r1_o, m2_16s, 0, 0, 0, cmps64)
/* COMPARE HALFWORD IMMEDIATE */
C(0xa70e, CHI, RI_a, Z, r1_o, i2, 0, 0, 0, cmps32)
C(0xa70f, CGHI, RI_a, Z, r1_o, i2, 0, 0, 0, cmps64)
C(0xe554, CHHSI, SIL, GIE, m1_16s, i2, 0, 0, 0, cmps64)
C(0xe55c, CHSI, SIL, GIE, m1_32s, i2, 0, 0, 0, cmps64)
C(0xe558, CGHSI, SIL, GIE, m1_64, i2, 0, 0, 0, cmps64)
/* COMPARE HALFWORD RELATIVE LONG */
C(0xc605, CHRL, RIL_a, GIE, r1_o, mri2_32s, 0, 0, 0, cmps32)
C(0xc604, CGHRL, RIL_a, GIE, r1_o, mri2_64, 0, 0, 0, cmps64)
/* COMPARE LOGICAL */
C(0x1500, CLR, RR_a, Z, r1, r2, 0, 0, 0, cmpu32)
C(0x5500, CL, RX_a, Z, r1, m2_32s, 0, 0, 0, cmpu32)
C(0xe355, CLY, RXY_a, LD, r1, m2_32s, 0, 0, 0, cmpu32)
C(0xb921, CLGR, RRE, Z, r1, r2, 0, 0, 0, cmpu64)
C(0xb931, CLGFR, RRE, Z, r1, r2_32u, 0, 0, 0, cmpu64)
C(0xe321, CLG, RXY_a, Z, r1, m2_64, 0, 0, 0, cmpu64)
C(0xe331, CLGF, RXY_a, Z, r1, m2_32u, 0, 0, 0, cmpu64)
C(0xd500, CLC, SS_a, Z, la1, a2, 0, 0, clc, 0)
/* COMPARE LOGICAL IMMEDIATE */
C(0xc20f, CLFI, RIL_a, EI, r1, i2, 0, 0, 0, cmpu32)
C(0xc20e, CLGFI, RIL_a, EI, r1, i2_32u, 0, 0, 0, cmpu64)
C(0x9500, CLI, SI, Z, m1_8u, i2_8u, 0, 0, 0, cmpu64)
C(0xeb55, CLIY, SIY, LD, m1_8u, i2_8u, 0, 0, 0, cmpu64)
C(0xe555, CLHHSI, SIL, GIE, m1_16u, i2_16u, 0, 0, 0, cmpu64)
C(0xe55d, CLFHSI, SIL, GIE, m1_32u, i2_16u, 0, 0, 0, cmpu64)
C(0xe559, CLGHSI, SIL, GIE, m1_64, i2_16u, 0, 0, 0, cmpu64)
/* COMPARE LOGICAL RELATIVE LONG */
C(0xc60f, CLRL, RIL_b, GIE, r1_o, mri2_32u, 0, 0, 0, cmpu32)
C(0xc60a, CLGRL, RIL_b, GIE, r1_o, mri2_64, 0, 0, 0, cmpu64)
C(0xc60e, CLGFRL, RIL_b, GIE, r1_o, mri2_32u, 0, 0, 0, cmpu64)
C(0xc607, CLHRL, RIL_b, GIE, r1_o, mri2_16u, 0, 0, 0, cmpu32)
C(0xc606, CLGHRL, RIL_b, GIE, r1_o, mri2_16u, 0, 0, 0, cmpu64)
/* COMPARE LOGICAL LONG EXTENDED */
C(0xa900, CLCLE, RS_a, Z, 0, a2, 0, 0, clcle, 0)
/* COMPARE LOGICAL CHARACTERS UNDER MASK */
C(0xbd00, CLM, RS_b, Z, r1_o, a2, 0, 0, clm, 0)
C(0xeb21, CLMY, RSY_b, LD, r1_o, a2, 0, 0, clm, 0)
C(0xeb20, CLMH, RSY_b, Z, r1_sr32, a2, 0, 0, clm, 0)
/* COMPARE LOGICAL STRING */
C(0xb25d, CLST, RRE, Z, r1_o, r2_o, 0, 0, clst, 0)
/* COMPARE AND BRANCH */
D(0xecf6, CRB, RRS, GIE, r1_32s, r2_32s, 0, 0, cj, 0, 0)
D(0xece4, CGRB, RRS, GIE, r1_o, r2_o, 0, 0, cj, 0, 0)
D(0xec76, CRJ, RIE_b, GIE, r1_32s, r2_32s, 0, 0, cj, 0, 0)
D(0xec64, CGRJ, RIE_b, GIE, r1_o, r2_o, 0, 0, cj, 0, 0)
D(0xecfe, CIB, RIS, GIE, r1_32s, i2, 0, 0, cj, 0, 0)
D(0xecfc, CGIB, RIS, GIE, r1_o, i2, 0, 0, cj, 0, 0)
D(0xec7e, CIJ, RIE_c, GIE, r1_32s, i2, 0, 0, cj, 0, 0)
D(0xec7c, CGIJ, RIE_c, GIE, r1_o, i2, 0, 0, cj, 0, 0)
/* COMPARE LOGICAL AND BRANCH */
D(0xecf7, CLRB, RRS, GIE, r1_32u, r2_32u, 0, 0, cj, 0, 1)
D(0xece5, CLGRB, RRS, GIE, r1_o, r2_o, 0, 0, cj, 0, 1)
D(0xec77, CLRJ, RIE_b, GIE, r1_32u, r2_32u, 0, 0, cj, 0, 1)
D(0xec65, CLGRJ, RIE_b, GIE, r1_o, r2_o, 0, 0, cj, 0, 1)
D(0xecff, CLIB, RIS, GIE, r1_32u, i2_8u, 0, 0, cj, 0, 1)
D(0xecfd, CLGIB, RIS, GIE, r1_o, i2_8u, 0, 0, cj, 0, 1)
D(0xec7f, CLIJ, RIE_c, GIE, r1_32u, i2_8u, 0, 0, cj, 0, 1)
D(0xec7d, CLGIJ, RIE_c, GIE, r1_o, i2_8u, 0, 0, cj, 0, 1)
/* COMPARE AND SWAP */
D(0xba00, CS, RS_a, Z, r3_32u, r1_32u, new, r1_32, cs, 0, 0)
D(0xeb14, CSY, RSY_a, LD, r3_32u, r1_32u, new, r1_32, cs, 0, 0)
D(0xeb30, CSG, RSY_a, Z, r3_o, r1_o, new, r1, cs, 0, 1)
/* COMPARE DOUBLE AND SWAP */
D(0xbb00, CDS, RS_a, Z, r3_D32, r1_D32, new, r1_D32, cs, 0, 1)
D(0xeb31, CDSY, RSY_a, LD, r3_D32, r1_D32, new, r1_D32, cs, 0, 1)
C(0xeb3e, CDSG, RSY_a, Z, 0, 0, 0, 0, cdsg, 0)
/* COMPARE AND TRAP */
D(0xb972, CRT, RRF_c, GIE, r1_32s, r2_32s, 0, 0, ct, 0, 0)
D(0xb960, CGRT, RRF_c, GIE, r1_o, r2_o, 0, 0, ct, 0, 0)
D(0xec72, CIT, RIE_a, GIE, r1_32s, i2, 0, 0, ct, 0, 0)
D(0xec70, CGIT, RIE_a, GIE, r1_o, i2, 0, 0, ct, 0, 0)
/* COMPARE LOGICAL AND TRAP */
D(0xb973, CLRT, RRF_c, GIE, r1_32u, r2_32u, 0, 0, ct, 0, 1)
D(0xb961, CLGRT, RRF_c, GIE, r1_o, r2_o, 0, 0, ct, 0, 1)
D(0xec73, CLFIT, RIE_a, GIE, r1_32u, i2_32u, 0, 0, ct, 0, 1)
D(0xec71, CLGIT, RIE_a, GIE, r1_o, i2_32u, 0, 0, ct, 0, 0)
/* CONVERT TO DECIMAL */
C(0x4e00, CVD, RX_a, Z, r1_o, a2, 0, 0, cvd, 0)
C(0xe326, CVDY, RXY_a, LD, r1_o, a2, 0, 0, cvd, 0)
/* CONVERT TO FIXED */
C(0xb398, CFEBR, RRF_e, Z, 0, e2, new, r1_32, cfeb, 0)
C(0xb399, CFDBR, RRF_e, Z, 0, f2_o, new, r1_32, cfdb, 0)
C(0xb39a, CFXBR, RRF_e, Z, 0, x2_o, new, r1_32, cfxb, 0)
C(0xb3a8, CGEBR, RRF_e, Z, 0, e2, r1, 0, cgeb, 0)
C(0xb3a9, CGDBR, RRF_e, Z, 0, f2_o, r1, 0, cgdb, 0)
C(0xb3aa, CGXBR, RRF_e, Z, 0, x2_o, r1, 0, cgxb, 0)
/* CONVERT FROM FIXED */
C(0xb394, CEFBR, RRF_e, Z, 0, r2_32s, new, e1, cegb, 0)
C(0xb395, CDFBR, RRF_e, Z, 0, r2_32s, f1, 0, cdgb, 0)
C(0xb396, CXFBR, RRF_e, Z, 0, r2_32s, x1, 0, cxgb, 0)
C(0xb3a4, CEGBR, RRF_e, Z, 0, r2_o, new, e1, cegb, 0)
C(0xb3a5, CDGBR, RRF_e, Z, 0, r2_o, f1, 0, cdgb, 0)
C(0xb3a6, CXGBR, RRF_e, Z, 0, r2_o, x1, 0, cxgb, 0)
/* CONVERT TO LOGICAL */
C(0xb39c, CLFEBR, RRF_e, FPE, 0, e2, new, r1_32, clfeb, 0)
C(0xb39d, CLFDBR, RRF_e, FPE, 0, f2_o, new, r1_32, clfdb, 0)
C(0xb39e, CLFXBR, RRF_e, FPE, 0, x2_o, new, r1_32, clfxb, 0)
C(0xb3ac, CLGEBR, RRF_e, FPE, 0, e2, r1, 0, clgeb, 0)
C(0xb3ad, CLGDBR, RRF_e, FPE, 0, f2_o, r1, 0, clgdb, 0)
C(0xb3ae, CLGXBR, RRF_e, FPE, 0, x2_o, r1, 0, clgxb, 0)
/* CONVERT FROM LOGICAL */
C(0xb390, CELFBR, RRF_e, FPE, 0, r2_32u, new, e1, celgb, 0)
C(0xb391, CDLFBR, RRF_e, FPE, 0, r2_32u, f1, 0, cdlgb, 0)
C(0xb392, CXLFBR, RRF_e, FPE, 0, r2_32u, x1, 0, cxlgb, 0)
C(0xb3a0, CELGBR, RRF_e, FPE, 0, r2_o, new, e1, celgb, 0)
C(0xb3a1, CDLGBR, RRF_e, FPE, 0, r2_o, f1, 0, cdlgb, 0)
C(0xb3a2, CXLGBR, RRF_e, FPE, 0, r2_o, x1, 0, cxlgb, 0)
/* DIVIDE */
C(0x1d00, DR, RR_a, Z, r1_D32, r2_32s, new_P, r1_P32, divs32, 0)
C(0x5d00, D, RX_a, Z, r1_D32, m2_32s, new_P, r1_P32, divs32, 0)
C(0xb30d, DEBR, RRE, Z, e1, e2, new, e1, deb, 0)
C(0xb31d, DDBR, RRE, Z, f1_o, f2_o, f1, 0, ddb, 0)
C(0xb34d, DXBR, RRE, Z, 0, x2_o, x1, 0, dxb, 0)
C(0xed0d, DEB, RXE, Z, e1, m2_32u, new, e1, deb, 0)
C(0xed1d, DDB, RXE, Z, f1_o, m2_64, f1, 0, ddb, 0)
/* DIVIDE LOGICAL */
C(0xb997, DLR, RRE, Z, r1_D32, r2_32u, new_P, r1_P32, divu32, 0)
C(0xe397, DL, RXY_a, Z, r1_D32, m2_32u, new_P, r1_P32, divu32, 0)
C(0xb987, DLGR, RRE, Z, 0, r2_o, r1_P, 0, divu64, 0)
C(0xe387, DLG, RXY_a, Z, 0, m2_64, r1_P, 0, divu64, 0)
/* DIVIDE SINGLE */
C(0xb90d, DSGR, RRE, Z, r1p1, r2, r1_P, 0, divs64, 0)
C(0xb91d, DSGFR, RRE, Z, r1p1, r2_32s, r1_P, 0, divs64, 0)
C(0xe30d, DSG, RXY_a, Z, r1p1, m2_64, r1_P, 0, divs64, 0)
C(0xe31d, DSGF, RXY_a, Z, r1p1, m2_32s, r1_P, 0, divs64, 0)
/* EXCLUSIVE OR */
C(0x1700, XR, RR_a, Z, r1, r2, new, r1_32, xor, nz32)
C(0xb9f7, XRK, RRF_a, DO, r2, r3, new, r1_32, xor, nz32)
C(0x5700, X, RX_a, Z, r1, m2_32s, new, r1_32, xor, nz32)
C(0xe357, XY, RXY_a, LD, r1, m2_32s, new, r1_32, xor, nz32)
C(0xb982, XGR, RRE, Z, r1, r2, r1, 0, xor, nz64)
C(0xb9e7, XGRK, RRF_a, DO, r2, r3, r1, 0, xor, nz64)
C(0xe382, XG, RXY_a, Z, r1, m2_64, r1, 0, xor, nz64)
C(0xd700, XC, SS_a, Z, 0, 0, 0, 0, xc, 0)
/* EXCLUSIVE OR IMMEDIATE */
D(0xc006, XIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, xori, 0, 0x2020)
D(0xc007, XILF, RIL_a, EI, r1_o, i2_32u, r1, 0, xori, 0, 0x2000)
C(0x9700, XI, SI, Z, m1_8u, i2_8u, new, m1_8, xor, nz64)
C(0xeb57, XIY, SIY, LD, m1_8u, i2_8u, new, m1_8, xor, nz64)
/* EXECUTE */
C(0x4400, EX, RX_a, Z, r1_o, a2, 0, 0, ex, 0)
/* EXECUTE RELATIVE LONG */
C(0xc600, EXRL, RIL_b, EE, r1_o, ri2, 0, 0, ex, 0)
/* EXTRACT ACCESS */
C(0xb24f, EAR, RRE, Z, 0, 0, new, r1_32, ear, 0)
/* EXTRACT FPC */
C(0xb38c, EFPC, RRE, Z, 0, 0, new, r1_32, efpc, 0)
/* FIND LEFTMOST ONE */
C(0xb983, FLOGR, RRE, EI, 0, r2_o, r1_P, 0, flogr, 0)
/* INSERT CHARACTER */
C(0x4300, IC, RX_a, Z, 0, m2_8u, 0, r1_8, mov2, 0)
C(0xe373, ICY, RXY_a, LD, 0, m2_8u, 0, r1_8, mov2, 0)
/* INSERT CHARACTERS UNDER MASK */
D(0xbf00, ICM, RS_b, Z, 0, a2, r1, 0, icm, 0, 0)
D(0xeb81, ICMY, RSY_b, LD, 0, a2, r1, 0, icm, 0, 0)
D(0xeb80, ICMH, RSY_b, Z, 0, a2, r1, 0, icm, 0, 32)
/* INSERT IMMEDIATE */
D(0xc008, IIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, insi, 0, 0x2020)
D(0xc009, IILF, RIL_a, EI, r1_o, i2_32u, r1, 0, insi, 0, 0x2000)
D(0xa500, IIHH, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1030)
D(0xa501, IIHL, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1020)
D(0xa502, IILH, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1010)
D(0xa503, IILL, RI_a, Z, r1_o, i2_16u, r1, 0, insi, 0, 0x1000)
/* INSERT PROGRAM MASK */
C(0xb222, IPM, RRE, Z, 0, 0, r1, 0, ipm, 0)
/* LOAD */
C(0x1800, LR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, 0)
C(0x5800, L, RX_a, Z, 0, a2, new, r1_32, ld32s, 0)
C(0xe358, LY, RXY_a, Z, 0, a2, new, r1_32, ld32s, 0)
C(0xb904, LGR, RRE, Z, 0, r2_o, 0, r1, mov2, 0)
C(0xb914, LGFR, RRE, Z, 0, r2_32s, 0, r1, mov2, 0)
C(0xe304, LG, RXY_a, Z, 0, a2, r1, 0, ld64, 0)
C(0xe314, LGF, RXY_a, Z, 0, a2, r1, 0, ld32s, 0)
C(0x2800, LDR, RR_a, Z, 0, f2_o, 0, f1, mov2, 0)
C(0x6800, LD, RX_a, Z, 0, m2_64, 0, f1, mov2, 0)
C(0xed65, LDY, RXY_a, LD, 0, m2_64, 0, f1, mov2, 0)
C(0x3800, LER, RR_a, Z, 0, e2, 0, cond_e1e2, mov2, 0)
C(0x7800, LE, RX_a, Z, 0, m2_32u, 0, e1, mov2, 0)
C(0xed64, LEY, RXY_a, LD, 0, m2_32u, 0, e1, mov2, 0)
C(0xb365, LXR, RRE, Z, 0, x2_o, 0, x1, movx, 0)
/* LOAD IMMEDIATE */
C(0xc001, LGFI, RIL_a, EI, 0, i2, 0, r1, mov2, 0)
/* LOAD RELATIVE LONG */
C(0xc40d, LRL, RIL_b, GIE, 0, ri2, new, r1_32, ld32s, 0)
C(0xc408, LGRL, RIL_b, GIE, 0, ri2, r1, 0, ld64, 0)
C(0xc40c, LGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32s, 0)
/* LOAD ADDRESS */
C(0x4100, LA, RX_a, Z, 0, a2, 0, r1, mov2, 0)
C(0xe371, LAY, RXY_a, LD, 0, a2, 0, r1, mov2, 0)
/* LOAD ADDRESS RELATIVE LONG */
C(0xc000, LARL, RIL_b, Z, 0, ri2, 0, r1, mov2, 0)
/* LOAD AND TEST */
C(0x1200, LTR, RR_a, Z, 0, r2_o, 0, cond_r1r2_32, mov2, s32)
C(0xb902, LTGR, RRE, Z, 0, r2_o, 0, r1, mov2, s64)
C(0xb912, LTGFR, RRE, Z, 0, r2_32s, 0, r1, mov2, s64)
C(0xe312, LT, RXY_a, EI, 0, a2, new, r1_32, ld32s, s64)
C(0xe302, LTG, RXY_a, EI, 0, a2, r1, 0, ld64, s64)
C(0xe332, LTGF, RXY_a, GIE, 0, a2, r1, 0, ld32s, s64)
C(0xb302, LTEBR, RRE, Z, 0, e2, 0, cond_e1e2, mov2, f32)
C(0xb312, LTDBR, RRE, Z, 0, f2_o, 0, f1, mov2, f64)
C(0xb342, LTXBR, RRE, Z, 0, x2_o, 0, x1, movx, f128)
/* LOAD BYTE */
C(0xb926, LBR, RRE, EI, 0, r2_8s, 0, r1_32, mov2, 0)
C(0xb906, LGBR, RRE, EI, 0, r2_8s, 0, r1, mov2, 0)
C(0xe376, LB, RXY_a, LD, 0, a2, new, r1_32, ld8s, 0)
C(0xe377, LGB, RXY_a, LD, 0, a2, r1, 0, ld8s, 0)
/* LOAD COMPLEMENT */
C(0x1300, LCR, RR_a, Z, 0, r2, new, r1_32, neg, neg32)
C(0xb903, LCGR, RRE, Z, 0, r2, r1, 0, neg, neg64)
C(0xb913, LCGFR, RRE, Z, 0, r2_32s, r1, 0, neg, neg64)
C(0xb303, LCEBR, RRE, Z, 0, e2, new, e1, negf32, f32)
C(0xb313, LCDBR, RRE, Z, 0, f2_o, f1, 0, negf64, f64)
C(0xb343, LCXBR, RRE, Z, 0, x2_o, x1, 0, negf128, f128)
C(0xb373, LCDFR, RRE, FPSSH, 0, f2_o, f1, 0, negf64, 0)
/* LOAD HALFWORD */
C(0xb927, LHR, RRE, EI, 0, r2_16s, 0, r1_32, mov2, 0)
C(0xb907, LGHR, RRE, EI, 0, r2_16s, 0, r1, mov2, 0)
C(0x4800, LH, RX_a, Z, 0, a2, new, r1_32, ld16s, 0)
C(0xe378, LHY, RXY_a, LD, 0, a2, new, r1_32, ld16s, 0)
C(0xe315, LGH, RXY_a, Z, 0, a2, r1, 0, ld16s, 0)
/* LOAD HALFWORD IMMEDIATE */
C(0xa708, LHI, RI_a, Z, 0, i2, 0, r1_32, mov2, 0)
C(0xa709, LGHI, RI_a, Z, 0, i2, 0, r1, mov2, 0)
/* LOAD HALFWORD RELATIVE LONG */
C(0xc405, LHRL, RIL_b, GIE, 0, ri2, new, r1_32, ld16s, 0)
C(0xc404, LGHRL, RIL_b, GIE, 0, ri2, r1, 0, ld16s, 0)
/* LOAD LOGICAL */
C(0xb916, LLGFR, RRE, Z, 0, r2_32u, 0, r1, mov2, 0)
C(0xe316, LLGF, RXY_a, Z, 0, a2, r1, 0, ld32u, 0)
/* LOAD LOGICAL RELATIVE LONG */
C(0xc40e, LLGFRL, RIL_b, GIE, 0, ri2, r1, 0, ld32u, 0)
/* LOAD LOGICAL CHARACTER */
C(0xb994, LLCR, RRE, EI, 0, r2_8u, 0, r1_32, mov2, 0)
C(0xb984, LLGCR, RRE, EI, 0, r2_8u, 0, r1, mov2, 0)
C(0xe394, LLC, RXY_a, EI, 0, a2, new, r1_32, ld8u, 0)
C(0xe390, LLGC, RXY_a, Z, 0, a2, r1, 0, ld8u, 0)
/* LOAD LOGICAL HALFWORD */
C(0xb995, LLHR, RRE, EI, 0, r2_16u, 0, r1_32, mov2, 0)
C(0xb985, LLGHR, RRE, EI, 0, r2_16u, 0, r1, mov2, 0)
C(0xe395, LLH, RXY_a, EI, 0, a2, new, r1_32, ld16u, 0)
C(0xe391, LLGH, RXY_a, Z, 0, a2, r1, 0, ld16u, 0)
/* LOAD LOGICAL HALFWORD RELATIVE LONG */
C(0xc402, LLHRL, RIL_b, GIE, 0, ri2, new, r1_32, ld16u, 0)
C(0xc406, LLGHRL, RIL_b, GIE, 0, ri2, r1, 0, ld16u, 0)
/* LOAD LOGICAL IMMEDATE */
D(0xc00e, LLIHF, RIL_a, EI, 0, i2_32u_shl, 0, r1, mov2, 0, 32)
D(0xc00f, LLILF, RIL_a, EI, 0, i2_32u_shl, 0, r1, mov2, 0, 0)
D(0xa50c, LLIHH, RI_a, Z, 0, i2_16u_shl, 0, r1, mov2, 0, 48)
D(0xa50d, LLIHL, RI_a, Z, 0, i2_16u_shl, 0, r1, mov2, 0, 32)
D(0xa50e, LLILH, RI_a, Z, 0, i2_16u_shl, 0, r1, mov2, 0, 16)
D(0xa50f, LLILL, RI_a, Z, 0, i2_16u_shl, 0, r1, mov2, 0, 0)
/* LOAD LOGICAL THIRTY ONE BITS */
C(0xb917, LLGTR, RRE, Z, 0, r2_o, r1, 0, llgt, 0)
C(0xe317, LLGT, RXY_a, Z, 0, m2_32u, r1, 0, llgt, 0)
/* LOAD FPR FROM GR */
C(0xb3c1, LDGR, RRE, FPRGR, 0, r2_o, 0, f1, mov2, 0)
/* LOAD GR FROM FPR */
C(0xb3cd, LGDR, RRE, FPRGR, 0, f2_o, 0, r1, mov2, 0)
/* LOAD NEGATIVE */
C(0x1100, LNR, RR_a, Z, 0, r2_32s, new, r1_32, nabs, nabs32)
C(0xb901, LNGR, RRE, Z, 0, r2, r1, 0, nabs, nabs64)
C(0xb911, LNGFR, RRE, Z, 0, r2_32s, r1, 0, nabs, nabs64)
C(0xb301, LNEBR, RRE, Z, 0, e2, new, e1, nabsf32, f32)
C(0xb311, LNDBR, RRE, Z, 0, f2_o, f1, 0, nabsf64, f64)
C(0xb341, LNXBR, RRE, Z, 0, x2_o, x1, 0, nabsf128, f128)
/* LOAD ON CONDITION */
C(0xb9f2, LOCR, RRF_c, LOC, r1, r2, new, r1_32, loc, 0)
C(0xb9e2, LOCGR, RRF_c, LOC, r1, r2, r1, 0, loc, 0)
C(0xebf2, LOC, RSY_b, LOC, r1, m2_32u, new, r1_32, loc, 0)
C(0xebe2, LOCG, RSY_b, LOC, r1, m2_64, r1, 0, loc, 0)
/* LOAD POSITIVE */
C(0x1000, LPR, RR_a, Z, 0, r2_32s, new, r1_32, abs, abs32)
C(0xb900, LPGR, RRE, Z, 0, r2, r1, 0, abs, abs64)
C(0xb910, LPGFR, RRE, Z, 0, r2_32s, r1, 0, abs, abs64)
C(0xb300, LPEBR, RRE, Z, 0, e2, new, e1, absf32, f32)
C(0xb310, LPDBR, RRE, Z, 0, f2_o, f1, 0, absf64, f64)
C(0xb340, LPXBR, RRE, Z, 0, x2_o, x1, 0, absf128, f128)
/* LOAD REVERSED */
C(0xb91f, LRVR, RRE, Z, 0, r2_32u, new, r1_32, rev32, 0)
C(0xb90f, LRVGR, RRE, Z, 0, r2_o, r1, 0, rev64, 0)
C(0xe31f, LRVH, RXY_a, Z, 0, m2_16u, new, r1_16, rev16, 0)
C(0xe31e, LRV, RXY_a, Z, 0, m2_32u, new, r1_32, rev32, 0)
C(0xe30f, LRVG, RXY_a, Z, 0, m2_64, r1, 0, rev64, 0)
/* LOAD ZERO */
C(0xb374, LZER, RRE, Z, 0, 0, 0, e1, zero, 0)
C(0xb375, LZDR, RRE, Z, 0, 0, 0, f1, zero, 0)
C(0xb376, LZXR, RRE, Z, 0, 0, 0, x1, zero2, 0)
/* LOAD FPC */
C(0xb29d, LFPC, S, Z, 0, m2_32u, 0, 0, sfpc, 0)
/* LOAD FPC AND SIGNAL */
C(0xb2bd, LFAS, S, IEEEE_SIM, 0, m2_32u, 0, 0, sfas, 0)
/* LOAD LENGTHENED */
C(0xb304, LDEBR, RRE, Z, 0, e2, f1, 0, ldeb, 0)
C(0xb305, LXDBR, RRE, Z, 0, f2_o, x1, 0, lxdb, 0)
C(0xb306, LXEBR, RRE, Z, 0, e2, x1, 0, lxeb, 0)
C(0xed04, LDEB, RXE, Z, 0, m2_32u, f1, 0, ldeb, 0)
C(0xed05, LXDB, RXE, Z, 0, m2_64, x1, 0, lxdb, 0)
C(0xed06, LXEB, RXE, Z, 0, m2_32u, x1, 0, lxeb, 0)
/* LOAD ROUNDED */
C(0xb344, LEDBR, RRE, Z, 0, f2_o, new, e1, ledb, 0)
C(0xb345, LDXBR, RRE, Z, 0, x2_o, f1, 0, ldxb, 0)
C(0xb346, LEXBR, RRE, Z, 0, x2_o, new, e1, lexb, 0)
/* LOAD MULTIPLE */
C(0x9800, LM, RS_a, Z, 0, a2, 0, 0, lm32, 0)
C(0xeb98, LMY, RSY_a, LD, 0, a2, 0, 0, lm32, 0)
C(0xeb04, LMG, RSY_a, Z, 0, a2, 0, 0, lm64, 0)
/* LOAD MULTIPLE HIGH */
C(0xeb96, LMH, RSY_a, Z, 0, a2, 0, 0, lmh, 0)
/* LOAD ACCESS MULTIPLE */
C(0x9a00, LAM, RS_a, Z, 0, a2, 0, 0, lam, 0)
C(0xeb9a, LAMY, RSY_a, LD, 0, a2, 0, 0, lam, 0)
/* MOVE */
C(0xd200, MVC, SS_a, Z, la1, a2, 0, 0, mvc, 0)
C(0xe544, MVHHI, SIL, GIE, la1, i2, 0, m1_16, mov2, 0)
C(0xe54c, MVHI, SIL, GIE, la1, i2, 0, m1_32, mov2, 0)
C(0xe548, MVGHI, SIL, GIE, la1, i2, 0, m1_64, mov2, 0)
C(0x9200, MVI, SI, Z, la1, i2, 0, m1_8, mov2, 0)
C(0xeb52, MVIY, SIY, LD, la1, i2, 0, m1_8, mov2, 0)
/* MOVE LONG */
C(0x0e00, MVCL, RR_a, Z, 0, 0, 0, 0, mvcl, 0)
/* MOVE LONG EXTENDED */
C(0xa800, MVCLE, RS_a, Z, 0, a2, 0, 0, mvcle, 0)
/* MOVE PAGE */
C(0xb254, MVPG, RRE, Z, r1_o, r2_o, 0, 0, mvpg, 0)
/* MOVE STRING */
C(0xb255, MVST, RRE, Z, r1_o, r2_o, 0, 0, mvst, 0)
/* MULTIPLY */
C(0x1c00, MR, RR_a, Z, r1p1_32s, r2_32s, new, r1_D32, mul, 0)
C(0x5c00, M, RX_a, Z, r1p1_32s, m2_32s, new, r1_D32, mul, 0)
C(0xe35c, MFY, RXY_a, GIE, r1p1_32s, m2_32s, new, r1_D32, mul, 0)
C(0xb317, MEEBR, RRE, Z, e1, e2, new, e1, meeb, 0)
C(0xb31c, MDBR, RRE, Z, f1_o, f2_o, f1, 0, mdb, 0)
C(0xb34c, MXBR, RRE, Z, 0, x2_o, x1, 0, mxb, 0)
C(0xb30c, MDEBR, RRE, Z, f1_o, e2, f1, 0, mdeb, 0)
C(0xb307, MXDBR, RRE, Z, 0, f2_o, x1, 0, mxdb, 0)
C(0xed17, MEEB, RXE, Z, e1, m2_32u, new, e1, meeb, 0)
C(0xed1c, MDB, RXE, Z, f1_o, m2_64, f1, 0, mdb, 0)
C(0xed0c, MDEB, RXE, Z, f1_o, m2_32u, f1, 0, mdeb, 0)
C(0xed07, MXDB, RXE, Z, 0, m2_64, x1, 0, mxdb, 0)
/* MULTIPLY HALFWORD */
C(0x4c00, MH, RX_a, Z, r1_o, m2_16s, new, r1_32, mul, 0)
C(0xe37c, MHY, RXY_a, GIE, r1_o, m2_16s, new, r1_32, mul, 0)
/* MULTIPLY HALFWORD IMMEDIATE */
C(0xa70c, MHI, RI_a, Z, r1_o, i2, new, r1_32, mul, 0)
C(0xa70d, MGHI, RI_a, Z, r1_o, i2, r1, 0, mul, 0)
/* MULTIPLY LOGICAL */
C(0xb996, MLR, RRE, Z, r1p1_32u, r2_32u, new, r1_D32, mul, 0)
C(0xe396, ML, RXY_a, Z, r1p1_32u, m2_32u, new, r1_D32, mul, 0)
C(0xb986, MLGR, RRE, Z, r1p1, r2_o, r1_P, 0, mul128, 0)
C(0xe386, MLG, RXY_a, Z, r1p1, m2_64, r1_P, 0, mul128, 0)
/* MULTIPLY SINGLE */
C(0xb252, MSR, RRE, Z, r1_o, r2_o, new, r1_32, mul, 0)
C(0x7100, MS, RX_a, Z, r1_o, m2_32s, new, r1_32, mul, 0)
C(0xe351, MSY, RXY_a, LD, r1_o, m2_32s, new, r1_32, mul, 0)
C(0xb90c, MSGR, RRE, Z, r1_o, r2_o, r1, 0, mul, 0)
C(0xb91c, MSGFR, RRE, Z, r1_o, r2_32s, r1, 0, mul, 0)
C(0xe30c, MSG, RXY_a, Z, r1_o, m2_64, r1, 0, mul, 0)
C(0xe31c, MSGF, RXY_a, Z, r1_o, m2_32s, r1, 0, mul, 0)
/* MULTIPLY SINGLE IMMEDIATE */
C(0xc201, MSFI, RIL_a, GIE, r1_o, i2, new, r1_32, mul, 0)
C(0xc200, MSGFI, RIL_a, GIE, r1_o, i2, r1, 0, mul, 0)
/* MULTIPLY AND ADD */
C(0xb30e, MAEBR, RRD, Z, e1, e2, new, e1, maeb, 0)
C(0xb31e, MADBR, RRD, Z, f1_o, f2_o, f1, 0, madb, 0)
C(0xed0e, MAEB, RXF, Z, e1, m2_32u, new, e1, maeb, 0)
C(0xed1e, MADB, RXF, Z, f1_o, m2_64, f1, 0, madb, 0)
/* MULTIPLY AND SUBTRACT */
C(0xb30f, MSEBR, RRD, Z, e1, e2, new, e1, mseb, 0)
C(0xb31f, MSDBR, RRD, Z, f1_o, f2_o, f1, 0, msdb, 0)
C(0xed0f, MSEB, RXF, Z, e1, m2_32u, new, e1, mseb, 0)
C(0xed1f, MSDB, RXF, Z, f1_o, m2_64, f1, 0, msdb, 0)
/* OR */
C(0x1600, OR, RR_a, Z, r1, r2, new, r1_32, or, nz32)
C(0xb9f6, ORK, RRF_a, DO, r2, r3, new, r1_32, or, nz32)
C(0x5600, O, RX_a, Z, r1, m2_32s, new, r1_32, or, nz32)
C(0xe356, OY, RXY_a, LD, r1, m2_32s, new, r1_32, or, nz32)
C(0xb981, OGR, RRE, Z, r1, r2, r1, 0, or, nz64)
C(0xb9e6, OGRK, RRF_a, DO, r2, r3, r1, 0, or, nz64)
C(0xe381, OG, RXY_a, Z, r1, m2_64, r1, 0, or, nz64)
C(0xd600, OC, SS_a, Z, la1, a2, 0, 0, oc, 0)
/* OR IMMEDIATE */
D(0xc00c, OIHF, RIL_a, EI, r1_o, i2_32u, r1, 0, ori, 0, 0x2020)
D(0xc00d, OILF, RIL_a, EI, r1_o, i2_32u, r1, 0, ori, 0, 0x2000)
D(0xa508, OIHH, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1030)
D(0xa509, OIHL, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1020)
D(0xa50a, OILH, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1010)
D(0xa50b, OILL, RI_a, Z, r1_o, i2_16u, r1, 0, ori, 0, 0x1000)
C(0x9600, OI, SI, Z, m1_8u, i2_8u, new, m1_8, or, nz64)
C(0xeb56, OIY, SIY, LD, m1_8u, i2_8u, new, m1_8, or, nz64)
/* PREFETCH */
/* Implemented as nops of course. */
C(0xe336, PFD, RXY_b, GIE, 0, 0, 0, 0, 0, 0)
C(0xc602, PFDRL, RIL_c, GIE, 0, 0, 0, 0, 0, 0)
/* POPULATION COUNT */
C(0xb9e1, POPCNT, RRE, PC, 0, r2_o, r1, 0, popcnt, nz64)
/* ROTATE LEFT SINGLE LOGICAL */
C(0xeb1d, RLL, RSY_a, Z, r3_o, sh32, new, r1_32, rll32, 0)
C(0xeb1c, RLLG, RSY_a, Z, r3_o, sh64, r1, 0, rll64, 0)
/* ROTATE THEN INSERT SELECTED BITS */
C(0xec55, RISBG, RIE_f, GIE, 0, r2, r1, 0, risbg, s64)
C(0xec5d, RISBHG, RIE_f, GIE, 0, r2, r1, 0, risbg, 0)
C(0xec51, RISBLG, RIE_f, GIE, 0, r2, r1, 0, risbg, 0)
/* ROTATE_THEN <OP> SELECTED BITS */
C(0xec54, RNSBG, RIE_f, GIE, 0, r2, r1, 0, rosbg, 0)
C(0xec56, ROSBG, RIE_f, GIE, 0, r2, r1, 0, rosbg, 0)
C(0xec57, RXSBG, RIE_f, GIE, 0, r2, r1, 0, rosbg, 0)
/* SEARCH STRING */
C(0xb25e, SRST, RRE, Z, r1_o, r2_o, 0, 0, srst, 0)
/* SET ACCESS */
C(0xb24e, SAR, RRE, Z, 0, r2_o, 0, 0, sar, 0)
/* SET FPC */
C(0xb384, SFPC, RRE, Z, 0, r1_o, 0, 0, sfpc, 0)
/* SET FPC AND SIGNAL */
C(0xb385, SFASR, RRE, IEEEE_SIM, 0, r1_o, 0, 0, sfas, 0)
/* SET BFP ROUNDING MODE */
C(0xb299, SRNM, S, Z, 0, 0, 0, 0, srnm, 0)
C(0xb2b8, SRNMB, S, FPE, 0, 0, 0, 0, srnm, 0)
/* SET DFP ROUNDING MODE */
C(0xb2b9, SRNMT, S, DFP, 0, 0, 0, 0, srnm, 0)
/* SHIFT LEFT SINGLE */
D(0x8b00, SLA, RS_a, Z, r1, sh32, new, r1_32, sla, 0, 31)
D(0xebdd, SLAK, RSY_a, DO, r3, sh32, new, r1_32, sla, 0, 31)
D(0xeb0b, SLAG, RSY_a, Z, r3, sh64, r1, 0, sla, 0, 63)
/* SHIFT LEFT SINGLE LOGICAL */
C(0x8900, SLL, RS_a, Z, r1_o, sh32, new, r1_32, sll, 0)
C(0xebdf, SLLK, RSY_a, DO, r3_o, sh32, new, r1_32, sll, 0)
C(0xeb0d, SLLG, RSY_a, Z, r3_o, sh64, r1, 0, sll, 0)
/* SHIFT RIGHT SINGLE */
C(0x8a00, SRA, RS_a, Z, r1_32s, sh32, new, r1_32, sra, s32)
C(0xebdc, SRAK, RSY_a, DO, r3_32s, sh32, new, r1_32, sra, s32)
C(0xeb0a, SRAG, RSY_a, Z, r3_o, sh64, r1, 0, sra, s64)
/* SHIFT RIGHT SINGLE LOGICAL */
C(0x8800, SRL, RS_a, Z, r1_32u, sh32, new, r1_32, srl, 0)
C(0xebde, SRLK, RSY_a, DO, r3_32u, sh32, new, r1_32, srl, 0)
C(0xeb0c, SRLG, RSY_a, Z, r3_o, sh64, r1, 0, srl, 0)
/* SHIFT LEFT DOUBLE */
D(0x8f00, SLDA, RS_a, Z, r1_D32, sh64, new, r1_D32, sla, 0, 31)
/* SHIFT LEFT DOUBLE LOGICAL */
C(0x8d00, SLDL, RS_a, Z, r1_D32, sh64, new, r1_D32, sll, 0)
/* SHIFT RIGHT DOUBLE */
C(0x8e00, SRDA, RS_a, Z, r1_D32, sh64, new, r1_D32, sra, s64)
/* SHIFT RIGHT DOUBLE LOGICAL */
C(0x8c00, SRDL, RS_a, Z, r1_D32, sh64, new, r1_D32, srl, 0)
/* SQUARE ROOT */
C(0xb314, SQEBR, RRE, Z, 0, e2, new, e1, sqeb, 0)
C(0xb315, SQDBR, RRE, Z, 0, f2_o, f1, 0, sqdb, 0)
C(0xb316, SQXBR, RRE, Z, 0, x2_o, x1, 0, sqxb, 0)
C(0xed14, SQEB, RXE, Z, 0, m2_32u, new, e1, sqeb, 0)
C(0xed15, SQDB, RXE, Z, 0, m2_64, f1, 0, sqdb, 0)
/* STORE */
C(0x5000, ST, RX_a, Z, r1_o, a2, 0, 0, st32, 0)
C(0xe350, STY, RXY_a, LD, r1_o, a2, 0, 0, st32, 0)
C(0xe324, STG, RXY_a, Z, r1_o, a2, 0, 0, st64, 0)
C(0x6000, STD, RX_a, Z, f1_o, a2, 0, 0, st64, 0)
C(0xed67, STDY, RXY_a, LD, f1_o, a2, 0, 0, st64, 0)
C(0x7000, STE, RX_a, Z, e1, a2, 0, 0, st32, 0)
C(0xed66, STEY, RXY_a, LD, e1, a2, 0, 0, st32, 0)
/* STORE RELATIVE LONG */
C(0xc40f, STRL, RIL_b, GIE, r1_o, ri2, 0, 0, st32, 0)
C(0xc40b, STGRL, RIL_b, GIE, r1_o, ri2, 0, 0, st64, 0)
/* STORE CHARACTER */
C(0x4200, STC, RX_a, Z, r1_o, a2, 0, 0, st8, 0)
C(0xe372, STCY, RXY_a, LD, r1_o, a2, 0, 0, st8, 0)
/* STORE CHARACTERS UNDER MASK */
D(0xbe00, STCM, RS_b, Z, r1_o, a2, 0, 0, stcm, 0, 0)
D(0xeb2d, STCMY, RSY_b, LD, r1_o, a2, 0, 0, stcm, 0, 0)
D(0xeb2c, STCMH, RSY_b, LD, r1_o, a2, 0, 0, stcm, 0, 32)
/* STORE HALFWORD */
C(0x4000, STH, RX_a, Z, r1_o, a2, 0, 0, st16, 0)
C(0xe370, STHY, RXY_a, LD, r1_o, a2, 0, 0, st16, 0)
/* STORE HALFWORD RELATIVE LONG */
C(0xc407, STHRL, RIL_b, GIE, r1_o, ri2, 0, 0, st16, 0)
/* STORE ON CONDITION */
D(0xebf3, STOC, RSY_b, LOC, 0, 0, 0, 0, soc, 0, 0)
D(0xebe3, STOCG, RSY_b, LOC, 0, 0, 0, 0, soc, 0, 1)
/* STORE REVERSED */
C(0xe33f, STRVH, RXY_a, Z, la2, r1_16u, new, m1_16, rev16, 0)
C(0xe33e, STRV, RXY_a, Z, la2, r1_32u, new, m1_32, rev32, 0)
C(0xe32f, STRVG, RXY_a, Z, la2, r1_o, new, m1_64, rev64, 0)
/* STORE FPC */
C(0xb29c, STFPC, S, Z, 0, a2, new, m2_32, efpc, 0)
/* STORE MULTIPLE */
D(0x9000, STM, RS_a, Z, 0, a2, 0, 0, stm, 0, 4)
D(0xeb90, STMY, RSY_a, LD, 0, a2, 0, 0, stm, 0, 4)
D(0xeb24, STMG, RSY_a, Z, 0, a2, 0, 0, stm, 0, 8)
/* STORE MULTIPLE HIGH */
C(0xeb26, STMH, RSY_a, Z, 0, a2, 0, 0, stmh, 0)
/* STORE ACCESS MULTIPLE */
C(0x9b00, STAM, RS_a, Z, 0, a2, 0, 0, stam, 0)
C(0xeb9b, STAMY, RSY_a, LD, 0, a2, 0, 0, stam, 0)
/* SUBTRACT */
C(0x1b00, SR, RR_a, Z, r1, r2, new, r1_32, sub, subs32)
C(0xb9f9, SRK, RRF_a, DO, r2, r3, new, r1_32, sub, subs32)
C(0x5b00, S, RX_a, Z, r1, m2_32s, new, r1_32, sub, subs32)
C(0xe35b, SY, RXY_a, LD, r1, m2_32s, new, r1_32, sub, subs32)
C(0xb909, SGR, RRE, Z, r1, r2, r1, 0, sub, subs64)
C(0xb919, SGFR, RRE, Z, r1, r2_32s, r1, 0, sub, subs64)
C(0xb9e9, SGRK, RRF_a, DO, r2, r3, r1, 0, sub, subs64)
C(0xe309, SG, RXY_a, Z, r1, m2_64, r1, 0, sub, subs64)
C(0xe319, SGF, RXY_a, Z, r1, m2_32s, r1, 0, sub, subs64)
C(0xb30b, SEBR, RRE, Z, e1, e2, new, e1, seb, f32)
C(0xb31b, SDBR, RRE, Z, f1_o, f2_o, f1, 0, sdb, f64)
C(0xb34b, SXBR, RRE, Z, 0, x2_o, x1, 0, sxb, f128)
C(0xed0b, SEB, RXE, Z, e1, m2_32u, new, e1, seb, f32)
C(0xed1b, SDB, RXE, Z, f1_o, m2_64, f1, 0, sdb, f64)
/* SUBTRACT HALFWORD */
C(0x4b00, SH, RX_a, Z, r1, m2_16s, new, r1_32, sub, subs32)
C(0xe37b, SHY, RXY_a, LD, r1, m2_16s, new, r1_32, sub, subs32)
/* SUBTRACT LOGICAL */
C(0x1f00, SLR, RR_a, Z, r1, r2, new, r1_32, sub, subu32)
C(0xb9fb, SLRK, RRF_a, DO, r2, r3, new, r1_32, sub, subu32)
C(0x5f00, SL, RX_a, Z, r1, m2_32u, new, r1_32, sub, subu32)
C(0xe35f, SLY, RXY_a, LD, r1, m2_32u, new, r1_32, sub, subu32)
C(0xb90b, SLGR, RRE, Z, r1, r2, r1, 0, sub, subu64)
C(0xb91b, SLGFR, RRE, Z, r1, r2_32u, r1, 0, sub, subu64)
C(0xb9eb, SLGRK, RRF_a, DO, r2, r3, r1, 0, sub, subu64)
C(0xe30b, SLG, RXY_a, Z, r1, m2_64, r1, 0, sub, subu64)
C(0xe31b, SLGF, RXY_a, Z, r1, m2_32u, r1, 0, sub, subu64)
/* SUBTRACT LOGICAL IMMEDIATE */
C(0xc205, SLFI, RIL_a, EI, r1, i2_32u, new, r1_32, sub, subu32)
C(0xc204, SLGFI, RIL_a, EI, r1, i2_32u, r1, 0, sub, subu64)
/* SUBTRACT LOGICAL WITH BORROW */
C(0xb999, SLBR, RRE, Z, r1, r2, new, r1_32, subb, subb32)
C(0xb989, SLBGR, RRE, Z, r1, r2, r1, 0, subb, subb64)
C(0xe399, SLB, RXY_a, Z, r1, m2_32u, new, r1_32, subb, subb32)
C(0xe389, SLBG, RXY_a, Z, r1, m2_64, r1, 0, subb, subb64)
/* SUPERVISOR CALL */
C(0x0a00, SVC, I, Z, 0, 0, 0, 0, svc, 0)
/* TEST DATA CLASS */
C(0xed10, TCEB, RXE, Z, e1, a2, 0, 0, tceb, 0)
C(0xed11, TCDB, RXE, Z, f1_o, a2, 0, 0, tcdb, 0)
C(0xed12, TCXB, RXE, Z, x1_o, a2, 0, 0, tcxb, 0)
/* TEST UNDER MASK */
C(0x9100, TM, SI, Z, m1_8u, i2_8u, 0, 0, 0, tm32)
C(0xeb51, TMY, SIY, LD, m1_8u, i2_8u, 0, 0, 0, tm32)
D(0xa702, TMHH, RI_a, Z, r1_o, i2_16u_shl, 0, 0, 0, tm64, 48)
D(0xa703, TMHL, RI_a, Z, r1_o, i2_16u_shl, 0, 0, 0, tm64, 32)
D(0xa700, TMLH, RI_a, Z, r1_o, i2_16u_shl, 0, 0, 0, tm64, 16)
D(0xa701, TMLL, RI_a, Z, r1_o, i2_16u_shl, 0, 0, 0, tm64, 0)
/* TRANSLATE */
C(0xdc00, TR, SS_a, Z, la1, a2, 0, 0, tr, 0)
/* UNPACK */
/* Really format SS_b, but we pack both lengths into one argument
for the helper call, so we might as well leave one 8-bit field. */
C(0xf300, UNPK, SS_a, Z, la1, a2, 0, 0, unpk, 0)
#ifndef CONFIG_USER_ONLY
/* COMPARE AND SWAP AND PURGE */
C(0xb250, CSP, RRE, Z, 0, ra2, 0, 0, csp, 0)
/* DIAGNOSE (KVM hypercall) */
C(0x8300, DIAG, RX_a, Z, 0, 0, 0, 0, diag, 0)
/* INSERT STORAGE KEY EXTENDED */
C(0xb229, ISKE, RRE, Z, 0, r2_o, new, r1_8, iske, 0)
/* INVALIDATE PAGE TABLE ENTRY */
C(0xb221, IPTE, RRF_a, Z, r1_o, r2_o, 0, 0, ipte, 0)
/* LOAD CONTROL */
C(0xb700, LCTL, RS_a, Z, 0, a2, 0, 0, lctl, 0)
C(0xeb2f, LCTLG, RSY_a, Z, 0, a2, 0, 0, lctlg, 0)
/* LOAD PSW */
C(0x8200, LPSW, S, Z, 0, a2, 0, 0, lpsw, 0)
/* LOAD PSW EXTENDED */
C(0xb2b2, LPSWE, S, Z, 0, a2, 0, 0, lpswe, 0)
/* LOAD REAL ADDRESS */
C(0xb100, LRA, RX_a, Z, 0, a2, r1, 0, lra, 0)
C(0xe313, LRAY, RXY_a, LD, 0, a2, r1, 0, lra, 0)
C(0xe303, LRAG, RXY_a, Z, 0, a2, r1, 0, lra, 0)
/* MOVE TO PRIMARY */
C(0xda00, MVCP, SS_d, Z, la1, a2, 0, 0, mvcp, 0)
/* MOVE TO SECONDARY */
C(0xdb00, MVCS, SS_d, Z, la1, a2, 0, 0, mvcs, 0)
/* PURGE TLB */
C(0xb20d, PTLB, S, Z, 0, 0, 0, 0, ptlb, 0)
/* RESET REFERENCE BIT EXTENDED */
C(0xb22a, RRBE, RRE, Z, 0, r2_o, 0, 0, rrbe, 0)
/* SERVICE CALL LOGICAL PROCESSOR (PV hypercall) */
C(0xb220, SERVC, RRE, Z, r1_o, r2_o, 0, 0, servc, 0)
/* SET ADDRESSING MODE */
/* We only do 64-bit, so accept this as a no-op.
Let SAM24 and SAM31 signal illegal instruction. */
C(0x010e, SAM64, E, Z, 0, 0, 0, 0, 0, 0)
/* SET ADDRESS SPACE CONTROL FAST */
C(0xb279, SACF, S, Z, 0, a2, 0, 0, sacf, 0)
/* SET CLOCK */
/* ??? Not implemented - is it necessary? */
C(0xb204, SCK, S, Z, 0, 0, 0, 0, 0, 0)
/* SET CLOCK COMPARATOR */
C(0xb206, SCKC, S, Z, 0, m2_64, 0, 0, sckc, 0)
/* SET CPU TIMER */
C(0xb208, SPT, S, Z, 0, m2_64, 0, 0, spt, 0)
/* SET PREFIX */
C(0xb210, SPX, S, Z, 0, m2_32u, 0, 0, spx, 0)
/* SET PSW KEY FROM ADDRESS */
C(0xb20a, SPKA, S, Z, 0, a2, 0, 0, spka, 0)
/* SET STORAGE KEY EXTENDED */
C(0xb22b, SSKE, RRF_c, Z, r1_o, r2_o, 0, 0, sske, 0)
/* SET SYSTEM MASK */
C(0x8000, SSM, S, Z, 0, m2_8u, 0, 0, ssm, 0)
/* SIGNAL PROCESSOR */
C(0xae00, SIGP, RS_a, Z, r3_o, a2, 0, 0, sigp, 0)
/* STORE CLOCK */
C(0xb205, STCK, S, Z, la2, 0, new, m1_64, stck, 0)
C(0xb27c, STCKF, S, Z, la2, 0, new, m1_64, stck, 0)
/* STORE CLOCK EXTENDED */
C(0xb278, STCKE, S, Z, 0, a2, 0, 0, stcke, 0)
/* STORE CLOCK COMPARATOR */
C(0xb207, STCKC, S, Z, la2, 0, new, m1_64, stckc, 0)
/* STORE CONTROL */
C(0xb600, STCTL, RS_a, Z, 0, a2, 0, 0, stctl, 0)
C(0xeb25, STCTG, RSY_a, Z, 0, a2, 0, 0, stctg, 0)
/* STORE CPU ADDRESS */
C(0xb212, STAP, S, Z, la2, 0, new, m1_16, stap, 0)
/* STORE CPU ID */
C(0xb202, STIDP, S, Z, la2, 0, new, m1_64, stidp, 0)
/* STORE CPU TIMER */
C(0xb209, STPT, S, Z, la2, 0, new, m1_64, stpt, 0)
/* STORE FACILITY LIST */
C(0xb2b1, STFL, S, Z, 0, 0, 0, 0, stfl, 0)
/* STORE PREFIX */
C(0xb211, STPX, S, Z, la2, 0, new, m1_32, stpx, 0)
/* STORE SYSTEM INFORMATION */
C(0xb27d, STSI, S, Z, 0, a2, 0, 0, stsi, 0)
/* STORE THEN AND SYSTEM MASK */
C(0xac00, STNSM, SI, Z, la1, 0, 0, 0, stnosm, 0)
/* STORE THEN OR SYSTEM MASK */
C(0xad00, STOSM, SI, Z, la1, 0, 0, 0, stnosm, 0)
/* STORE USING REAL ADDRESS */
C(0xb246, STURA, RRE, Z, r1_o, r2_o, 0, 0, stura, 0)
/* TEST PROTECTION */
C(0xe501, TPROT, SSE, Z, la1, a2, 0, 0, tprot, 0)
/* I/O Instructions. For each we simply indicate non-operation. */
C(0xb276, XSCH, S, Z, 0, 0, 0, 0, subchannel, 0)
C(0xb230, CSCH, S, Z, 0, 0, 0, 0, subchannel, 0)
C(0xb231, HSCH, S, Z, 0, 0, 0, 0, subchannel, 0)
C(0xb232, MSCH, S, Z, 0, 0, 0, 0, subchannel, 0)
C(0xb23b, RCHP, S, Z, 0, 0, 0, 0, subchannel, 0)
C(0xb238, RSCH, S, Z, 0, 0, 0, 0, subchannel, 0)
C(0xb233, SSCH, S, Z, 0, 0, 0, 0, subchannel, 0)
C(0xb234, STSCH, S, Z, 0, 0, 0, 0, subchannel, 0)
C(0xb235, TSCH, S, Z, 0, 0, 0, 0, subchannel, 0)
/* ??? Not listed in PoO ninth edition, but there's a linux driver that
uses it: "A CHSC subchannel is usually present on LPAR only." */
C(0xb25f, CHSC, S, Z, 0, 0, 0, 0, subchannel, 0)
#endif /* CONFIG_USER_ONLY */

View File

@ -0,0 +1,55 @@
/* Description of s390 insn formats. */
/* NAME F1, F2... */
F0(E)
F1(I, I(1, 8, 8))
F2(RI_a, R(1, 8), I(2,16,16))
F2(RI_b, R(1, 8), I(2,16,16))
F2(RI_c, M(1, 8), I(2,16,16))
F3(RIE_a, R(1, 8), I(2,16,16), M(3,32))
F4(RIE_b, R(1, 8), R(2,12), M(3,32), I(4,16,16))
F4(RIE_c, R(1, 8), I(2,32, 8), M(3,12), I(4,16,16))
F3(RIE_d, R(1, 8), I(2,16,16), R(3,12))
F3(RIE_e, R(1, 8), I(2,16,16), R(3,12))
F5(RIE_f, R(1, 8), R(2,12), I(3,16,8), I(4,24,8), I(5,32,8))
F2(RIL_a, R(1, 8), I(2,16,32))
F2(RIL_b, R(1, 8), I(2,16,32))
F2(RIL_c, M(1, 8), I(2,16,32))
F4(RIS, R(1, 8), I(2,32, 8), M(3,12), BD(4,16,20))
/* ??? The PoO does not call out subtypes _a and _b for RR, as it does
for e.g. RX. Our checking requires this for e.g. BCR. */
F2(RR_a, R(1, 8), R(2,12))
F2(RR_b, M(1, 8), R(2,12))
F2(RRE, R(1,24), R(2,28))
F3(RRD, R(1,16), R(2,28), R(3,24))
F4(RRF_a, R(1,24), R(2,28), R(3,16), M(4,20))
F4(RRF_b, R(1,24), R(2,28), R(3,16), M(4,20))
F4(RRF_c, R(1,24), R(2,28), M(3,16), M(4,20))
F4(RRF_d, R(1,24), R(2,28), M(3,16), M(4,20))
F4(RRF_e, R(1,24), R(2,28), M(3,16), M(4,20))
F4(RRS, R(1, 8), R(2,12), M(3,32), BD(4,16,20))
F3(RS_a, R(1, 8), BD(2,16,20), R(3,12))
F3(RS_b, R(1, 8), BD(2,16,20), M(3,12))
F3(RSI, R(1, 8), I(2,16,16), R(3,12))
F2(RSL, L(1, 8, 4), BD(1,16,20))
F3(RSY_a, R(1, 8), BDL(2), R(3,12))
F3(RSY_b, R(1, 8), BDL(2), M(3,12))
F2(RX_a, R(1, 8), BXD(2))
F2(RX_b, M(1, 8), BXD(2))
F2(RXE, R(1, 8), BXD(2))
F3(RXF, R(1,32), BXD(2), R(3, 8))
F2(RXY_a, R(1, 8), BXDL(2))
F2(RXY_b, M(1, 8), BXDL(2))
F1(S, BD(2,16,20))
F2(SI, BD(1,16,20), I(2,8,8))
F2(SIL, BD(1,16,20), I(2,32,16))
F2(SIY, BDL(1), I(2, 8, 8))
F3(SS_a, L(1, 8, 8), BD(1,16,20), BD(2,32,36))
F4(SS_b, L(1, 8, 4), BD(1,16,20), L(2,12,4), BD(2,32,36))
F4(SS_c, L(1, 8, 4), BD(1,16,20), BD(2,32,36), I(3,12, 4))
/* ??? Odd man out. The L1 field here is really a register, but the
easy way to compress the fields has R1 and B1 overlap. */
F4(SS_d, L(1, 8, 4), BD(1,16,20), BD(2,32,36), R(3,12))
F4(SS_e, R(1, 8), BD(2,16,20), R(3,12), BD(4,32,36))
F3(SS_f, BD(1,16,20), L(2,8,8), BD(2,32,36))
F2(SSE, BD(1,16,20), BD(2,32,36))
F3(SSF, BD(1,16,20), BD(2,32,36), R(3,8))

View File

@ -30,46 +30,97 @@
#endif
/* 64/64 -> 128 unsigned multiplication */
void HELPER(mlg)(CPUS390XState *env, uint32_t r1, uint64_t v2)
uint64_t HELPER(mul128)(CPUS390XState *env, uint64_t v1, uint64_t v2)
{
#if HOST_LONG_BITS == 64 && defined(__GNUC__)
/* assuming 64-bit hosts have __uint128_t */
__uint128_t res = (__uint128_t)env->regs[r1 + 1];
uint64_t reth;
mulu64(&env->retxl, &reth, v1, v2);
return reth;
}
res *= (__uint128_t)v2;
env->regs[r1] = (uint64_t)(res >> 64);
env->regs[r1 + 1] = (uint64_t)res;
#else
mulu64(&env->regs[r1 + 1], &env->regs[r1], env->regs[r1 + 1], v2);
#endif
/* 64/32 -> 32 signed division */
int64_t HELPER(divs32)(CPUS390XState *env, int64_t a, int64_t b64)
{
int32_t ret, b = b64;
int64_t q;
if (b == 0) {
runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
}
ret = q = a / b;
env->retxl = a % b;
/* Catch non-representable quotient. */
if (ret != q) {
runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
}
return ret;
}
/* 64/32 -> 32 unsigned division */
uint64_t HELPER(divu32)(CPUS390XState *env, uint64_t a, uint64_t b64)
{
uint32_t ret, b = b64;
uint64_t q;
if (b == 0) {
runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
}
ret = q = a / b;
env->retxl = a % b;
/* Catch non-representable quotient. */
if (ret != q) {
runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
}
return ret;
}
/* 64/64 -> 64 signed division */
int64_t HELPER(divs64)(CPUS390XState *env, int64_t a, int64_t b)
{
/* Catch divide by zero, and non-representable quotient (MIN / -1). */
if (b == 0 || (b == -1 && a == (1ll << 63))) {
runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
}
env->retxl = a % b;
return a / b;
}
/* 128 -> 64/64 unsigned division */
void HELPER(dlg)(CPUS390XState *env, uint32_t r1, uint64_t v2)
uint64_t HELPER(divu64)(CPUS390XState *env, uint64_t ah, uint64_t al,
uint64_t b)
{
uint64_t divisor = v2;
if (!env->regs[r1]) {
uint64_t ret;
/* Signal divide by zero. */
if (b == 0) {
runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
}
if (ah == 0) {
/* 64 -> 64/64 case */
env->regs[r1] = env->regs[r1 + 1] % divisor;
env->regs[r1 + 1] = env->regs[r1 + 1] / divisor;
return;
env->retxl = al % b;
ret = al / b;
} else {
/* ??? Move i386 idivq helper to host-utils. */
#if HOST_LONG_BITS == 64 && defined(__GNUC__)
/* assuming 64-bit hosts have __uint128_t */
__uint128_t dividend = (((__uint128_t)env->regs[r1]) << 64) |
(env->regs[r1 + 1]);
__uint128_t quotient = dividend / divisor;
__uint128_t remainder = dividend % divisor;
env->regs[r1 + 1] = quotient;
env->regs[r1] = remainder;
__uint128_t a = ((__uint128_t)ah << 64) | al;
__uint128_t q = a / b;
env->retxl = a % b;
ret = q;
if (ret != q) {
runtime_exception(env, PGM_FIXPT_DIVIDE, GETPC());
}
#else
/* 32-bit hosts would need special wrapper functionality - just abort if
we encounter such a case; it's very unlikely anyways. */
cpu_abort(env, "128 -> 64/64 division not implemented\n");
#endif
}
return ret;
}
/* absolute value 32-bit */
@ -114,69 +165,10 @@ int64_t HELPER(nabs_i64)(int64_t val)
}
}
/* add with carry 32-bit unsigned */
uint32_t HELPER(addc_u32)(uint32_t cc, uint32_t v1, uint32_t v2)
/* count leading zeros, for find leftmost one */
uint64_t HELPER(clz)(uint64_t v)
{
uint32_t res;
res = v1 + v2;
if (cc & 2) {
res++;
}
return res;
}
/* subtract unsigned v2 from v1 with borrow */
uint32_t HELPER(slb)(CPUS390XState *env, uint32_t cc, uint32_t r1, uint32_t v2)
{
uint32_t v1 = env->regs[r1];
uint32_t res = v1 + (~v2) + (cc >> 1);
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | res;
if (cc & 2) {
/* borrow */
return v1 ? 1 : 0;
} else {
return v1 ? 3 : 2;
}
}
/* subtract unsigned v2 from v1 with borrow */
uint32_t HELPER(slbg)(CPUS390XState *env, uint32_t cc, uint32_t r1,
uint64_t v1, uint64_t v2)
{
uint64_t res = v1 + (~v2) + (cc >> 1);
env->regs[r1] = res;
if (cc & 2) {
/* borrow */
return v1 ? 1 : 0;
} else {
return v1 ? 3 : 2;
}
}
/* find leftmost one */
uint32_t HELPER(flogr)(CPUS390XState *env, uint32_t r1, uint64_t v2)
{
uint64_t res = 0;
uint64_t ov2 = v2;
while (!(v2 & 0x8000000000000000ULL) && v2) {
v2 <<= 1;
res++;
}
if (!v2) {
env->regs[r1] = 64;
env->regs[r1 + 1] = 0;
return 0;
} else {
env->regs[r1] = res;
env->regs[r1 + 1] = ov2 & ~(0x8000000000000000ULL >> res);
return 2;
}
return clz64(v);
}
uint64_t HELPER(cvd)(int32_t bin)
@ -199,3 +191,15 @@ uint64_t HELPER(cvd)(int32_t bin)
return dec;
}
uint64_t HELPER(popcnt)(uint64_t r2)
{
uint64_t ret = 0;
int i;
for (i = 0; i < 64; i += 8) {
uint64_t t = ctpop32((r2 >> i) & 0xff);
ret |= t << i;
}
return ret;
}

View File

@ -304,214 +304,142 @@ uint32_t HELPER(clm)(CPUS390XState *env, uint32_t r1, uint32_t mask,
return cc;
}
/* store character under mask */
void HELPER(stcm)(CPUS390XState *env, uint32_t r1, uint32_t mask,
uint64_t addr)
static inline uint64_t fix_address(CPUS390XState *env, uint64_t a)
{
uint8_t r;
HELPER_LOG("%s: r1 0x%x mask 0x%x addr 0x%lx\n", __func__, r1, mask,
addr);
while (mask) {
if (mask & 8) {
r = (r1 & 0xff000000UL) >> 24;
cpu_stb_data(env, addr, r);
HELPER_LOG("mask 0x%x %02x (0x%lx) ", mask, r, addr);
addr++;
}
mask = (mask << 1) & 0xf;
r1 <<= 8;
/* 31-Bit mode */
if (!(env->psw.mask & PSW_MASK_64)) {
a &= 0x7fffffff;
}
HELPER_LOG("\n");
return a;
}
static inline uint64_t get_address(CPUS390XState *env, int x2, int b2, int d2)
{
uint64_t r = d2;
if (x2) {
r += env->regs[x2];
}
if (b2) {
r += env->regs[b2];
}
/* 31-Bit mode */
if (!(env->psw.mask & PSW_MASK_64)) {
r &= 0x7fffffff;
}
return r;
return fix_address(env, r);
}
static inline uint64_t get_address_31fix(CPUS390XState *env, int reg)
{
uint64_t r = env->regs[reg];
/* 31-Bit mode */
if (!(env->psw.mask & PSW_MASK_64)) {
r &= 0x7fffffff;
}
return r;
return fix_address(env, env->regs[reg]);
}
/* search string (c is byte to search, r2 is string, r1 end of string) */
uint32_t HELPER(srst)(CPUS390XState *env, uint32_t c, uint32_t r1, uint32_t r2)
uint64_t HELPER(srst)(CPUS390XState *env, uint64_t r0, uint64_t end,
uint64_t str)
{
uint64_t i;
uint32_t cc = 2;
uint64_t str = get_address_31fix(env, r2);
uint64_t end = get_address_31fix(env, r1);
uint32_t len;
uint8_t v, c = r0;
HELPER_LOG("%s: c %d *r1 0x%" PRIx64 " *r2 0x%" PRIx64 "\n", __func__,
c, env->regs[r1], env->regs[r2]);
str = fix_address(env, str);
end = fix_address(env, end);
for (i = str; i != end; i++) {
if (cpu_ldub_data(env, i) == c) {
env->regs[r1] = i;
cc = 1;
break;
/* Assume for now that R2 is unmodified. */
env->retxl = str;
/* Lest we fail to service interrupts in a timely manner, limit the
amount of work we're willing to do. For now, lets cap at 8k. */
for (len = 0; len < 0x2000; ++len) {
if (str + len == end) {
/* Character not found. R1 & R2 are unmodified. */
env->cc_op = 2;
return end;
}
v = cpu_ldub_data(env, str + len);
if (v == c) {
/* Character found. Set R1 to the location; R2 is unmodified. */
env->cc_op = 1;
return str + len;
}
}
return cc;
/* CPU-determined bytes processed. Advance R2 to next byte to process. */
env->retxl = str + len;
env->cc_op = 3;
return end;
}
/* unsigned string compare (c is string terminator) */
uint32_t HELPER(clst)(CPUS390XState *env, uint32_t c, uint32_t r1, uint32_t r2)
uint64_t HELPER(clst)(CPUS390XState *env, uint64_t c, uint64_t s1, uint64_t s2)
{
uint64_t s1 = get_address_31fix(env, r1);
uint64_t s2 = get_address_31fix(env, r2);
uint8_t v1, v2;
uint32_t cc;
uint32_t len;
c = c & 0xff;
#ifdef CONFIG_USER_ONLY
if (!c) {
HELPER_LOG("%s: comparing '%s' and '%s'\n",
__func__, (char *)g2h(s1), (char *)g2h(s2));
}
#endif
for (;;) {
v1 = cpu_ldub_data(env, s1);
v2 = cpu_ldub_data(env, s2);
if ((v1 == c || v2 == c) || (v1 != v2)) {
break;
s1 = fix_address(env, s1);
s2 = fix_address(env, s2);
/* Lest we fail to service interrupts in a timely manner, limit the
amount of work we're willing to do. For now, lets cap at 8k. */
for (len = 0; len < 0x2000; ++len) {
uint8_t v1 = cpu_ldub_data(env, s1 + len);
uint8_t v2 = cpu_ldub_data(env, s2 + len);
if (v1 == v2) {
if (v1 == c) {
/* Equal. CC=0, and don't advance the registers. */
env->cc_op = 0;
env->retxl = s2;
return s1;
}
} else {
/* Unequal. CC={1,2}, and advance the registers. Note that
the terminator need not be zero, but the string that contains
the terminator is by definition "low". */
env->cc_op = (v1 == c ? 1 : v2 == c ? 2 : v1 < v2 ? 1 : 2);
env->retxl = s2 + len;
return s1 + len;
}
s1++;
s2++;
}
if (v1 == v2) {
cc = 0;
} else {
cc = (v1 < v2) ? 1 : 2;
/* FIXME: 31-bit mode! */
env->regs[r1] = s1;
env->regs[r2] = s2;
}
return cc;
/* CPU-determined bytes equal; advance the registers. */
env->cc_op = 3;
env->retxl = s2 + len;
return s1 + len;
}
/* move page */
void HELPER(mvpg)(CPUS390XState *env, uint64_t r0, uint64_t r1, uint64_t r2)
{
/* XXX missing r0 handling */
env->cc_op = 0;
#ifdef CONFIG_USER_ONLY
int i;
for (i = 0; i < TARGET_PAGE_SIZE; i++) {
cpu_stb_data(env, r1 + i, cpu_ldub_data(env, r2 + i));
}
memmove(g2h(r1), g2h(r2), TARGET_PAGE_SIZE);
#else
mvc_fast_memmove(env, TARGET_PAGE_SIZE, r1, r2);
#endif
}
/* string copy (c is string terminator) */
void HELPER(mvst)(CPUS390XState *env, uint32_t c, uint32_t r1, uint32_t r2)
uint64_t HELPER(mvst)(CPUS390XState *env, uint64_t c, uint64_t d, uint64_t s)
{
uint64_t dest = get_address_31fix(env, r1);
uint64_t src = get_address_31fix(env, r2);
uint8_t v;
uint32_t len;
c = c & 0xff;
#ifdef CONFIG_USER_ONLY
if (!c) {
HELPER_LOG("%s: copy '%s' to 0x%lx\n", __func__, (char *)g2h(src),
dest);
}
#endif
for (;;) {
v = cpu_ldub_data(env, src);
cpu_stb_data(env, dest, v);
d = fix_address(env, d);
s = fix_address(env, s);
/* Lest we fail to service interrupts in a timely manner, limit the
amount of work we're willing to do. For now, lets cap at 8k. */
for (len = 0; len < 0x2000; ++len) {
uint8_t v = cpu_ldub_data(env, s + len);
cpu_stb_data(env, d + len, v);
if (v == c) {
break;
/* Complete. Set CC=1 and advance R1. */
env->cc_op = 1;
env->retxl = s;
return d + len;
}
src++;
dest++;
}
env->regs[r1] = dest; /* FIXME: 31-bit mode! */
}
/* compare and swap 64-bit */
uint32_t HELPER(csg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
/* FIXME: locking? */
uint32_t cc;
uint64_t v2 = cpu_ldq_data(env, a2);
if (env->regs[r1] == v2) {
cc = 0;
cpu_stq_data(env, a2, env->regs[r3]);
} else {
cc = 1;
env->regs[r1] = v2;
}
return cc;
}
/* compare double and swap 64-bit */
uint32_t HELPER(cdsg)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
/* FIXME: locking? */
uint32_t cc;
uint64_t v2_hi = cpu_ldq_data(env, a2);
uint64_t v2_lo = cpu_ldq_data(env, a2 + 8);
uint64_t v1_hi = env->regs[r1];
uint64_t v1_lo = env->regs[r1 + 1];
if ((v1_hi == v2_hi) && (v1_lo == v2_lo)) {
cc = 0;
cpu_stq_data(env, a2, env->regs[r3]);
cpu_stq_data(env, a2 + 8, env->regs[r3 + 1]);
} else {
cc = 1;
env->regs[r1] = v2_hi;
env->regs[r1 + 1] = v2_lo;
}
return cc;
}
/* compare and swap 32-bit */
uint32_t HELPER(cs)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
/* FIXME: locking? */
uint32_t cc;
uint32_t v2 = cpu_ldl_data(env, a2);
HELPER_LOG("%s: r1 %d a2 0x%lx r3 %d\n", __func__, r1, a2, r3);
if (((uint32_t)env->regs[r1]) == v2) {
cc = 0;
cpu_stl_data(env, a2, (uint32_t)env->regs[r3]);
} else {
cc = 1;
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) | v2;
}
return cc;
/* Incomplete. Set CC=3 and signal to advance R1 and R2. */
env->cc_op = 3;
env->retxl = s + len;
return d + len;
}
static uint32_t helper_icm(CPUS390XState *env, uint32_t r1, uint64_t address,
@ -594,7 +522,7 @@ uint32_t HELPER(ex)(CPUS390XState *env, uint32_t cc, uint64_t v1,
HELPER_LOG("%s: svc %ld via execute\n", __func__, (insn | v1) & 0xff);
env->psw.addr = ret - 4;
env->int_svc_code = (insn | v1) & 0xff;
env->int_svc_ilc = 4;
env->int_svc_ilen = 4;
helper_exception(env, EXCP_SVC);
} else if ((insn & 0xff00) == 0xbf00) {
uint32_t insn2, r1, r3, b2, d2;
@ -613,55 +541,6 @@ uint32_t HELPER(ex)(CPUS390XState *env, uint32_t cc, uint64_t v1,
return cc;
}
/* store character under mask high operates on the upper half of r1 */
void HELPER(stcmh)(CPUS390XState *env, uint32_t r1, uint64_t address,
uint32_t mask)
{
int pos = 56; /* top of the upper half of r1 */
while (mask) {
if (mask & 8) {
cpu_stb_data(env, address, (env->regs[r1] >> pos) & 0xff);
address++;
}
mask = (mask << 1) & 0xf;
pos -= 8;
}
}
/* insert character under mask high; same as icm, but operates on the
upper half of r1 */
uint32_t HELPER(icmh)(CPUS390XState *env, uint32_t r1, uint64_t address,
uint32_t mask)
{
int pos = 56; /* top of the upper half of r1 */
uint64_t rmask = 0xff00000000000000ULL;
uint8_t val = 0;
int ccd = 0;
uint32_t cc = 0;
while (mask) {
if (mask & 8) {
env->regs[r1] &= ~rmask;
val = cpu_ldub_data(env, address);
if ((val & 0x80) && !ccd) {
cc = 1;
}
ccd = 1;
if (val && cc == 0) {
cc = 2;
}
env->regs[r1] |= (uint64_t)val << pos;
address++;
}
mask = (mask << 1) & 0xf;
pos -= 8;
rmask >>= 8;
}
return cc;
}
/* load access registers r1 to r3 from memory at a2 */
void HELPER(lam)(CPUS390XState *env, uint32_t r1, uint64_t a2, uint32_t r3)
{
@ -822,42 +701,49 @@ uint32_t HELPER(clcle)(CPUS390XState *env, uint32_t r1, uint64_t a2,
}
/* checksum */
void HELPER(cksm)(CPUS390XState *env, uint32_t r1, uint32_t r2)
uint64_t HELPER(cksm)(CPUS390XState *env, uint64_t r1,
uint64_t src, uint64_t src_len)
{
uint64_t src = get_address_31fix(env, r2);
uint64_t src_len = env->regs[(r2 + 1) & 15];
uint64_t cksm = (uint32_t)env->regs[r1];
uint64_t max_len, len;
uint64_t cksm = (uint32_t)r1;
while (src_len >= 4) {
cksm += cpu_ldl_data(env, src);
/* Lest we fail to service interrupts in a timely manner, limit the
amount of work we're willing to do. For now, lets cap at 8k. */
max_len = (src_len > 0x2000 ? 0x2000 : src_len);
/* move to next word */
src_len -= 4;
src += 4;
/* Process full words as available. */
for (len = 0; len + 4 <= max_len; len += 4, src += 4) {
cksm += (uint32_t)cpu_ldl_data(env, src);
}
switch (src_len) {
case 0:
break;
switch (max_len - len) {
case 1:
cksm += cpu_ldub_data(env, src) << 24;
len += 1;
break;
case 2:
cksm += cpu_lduw_data(env, src) << 16;
len += 2;
break;
case 3:
cksm += cpu_lduw_data(env, src) << 16;
cksm += cpu_ldub_data(env, src + 2) << 8;
len += 3;
break;
}
/* indicate we've processed everything */
env->regs[r2] = src + src_len;
env->regs[(r2 + 1) & 15] = 0;
/* Fold the carry from the checksum. Note that we can see carry-out
during folding more than once (but probably not more than twice). */
while (cksm > 0xffffffffull) {
cksm = (uint32_t)cksm + (cksm >> 32);
}
/* store result */
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
((uint32_t)cksm + (cksm >> 32));
/* Indicate whether or not we've processed everything. */
env->cc_op = (len == src_len ? 0 : 3);
/* Return both cksm and processed length. */
env->retxl = cksm;
return len;
}
void HELPER(unpk)(CPUS390XState *env, uint32_t len, uint64_t dest,
@ -1007,7 +893,7 @@ uint64_t HELPER(iske)(CPUS390XState *env, uint64_t r2)
}
/* set storage key extended */
void HELPER(sske)(CPUS390XState *env, uint32_t r1, uint64_t r2)
void HELPER(sske)(CPUS390XState *env, uint64_t r1, uint64_t r2)
{
uint64_t addr = get_address(env, 0, 0, r2);
@ -1019,7 +905,7 @@ void HELPER(sske)(CPUS390XState *env, uint32_t r1, uint64_t r2)
}
/* reset reference bit extended */
uint32_t HELPER(rrbe)(CPUS390XState *env, uint32_t r1, uint64_t r2)
uint32_t HELPER(rrbe)(CPUS390XState *env, uint64_t r2)
{
uint8_t re;
uint8_t key;
@ -1045,16 +931,16 @@ uint32_t HELPER(rrbe)(CPUS390XState *env, uint32_t r1, uint64_t r2)
}
/* compare and swap and purge */
uint32_t HELPER(csp)(CPUS390XState *env, uint32_t r1, uint32_t r2)
uint32_t HELPER(csp)(CPUS390XState *env, uint32_t r1, uint64_t r2)
{
uint32_t cc;
uint32_t o1 = env->regs[r1];
uint64_t a2 = get_address_31fix(env, r2) & ~3ULL;
uint64_t a2 = r2 & ~3ULL;
uint32_t o2 = cpu_ldl_data(env, a2);
if (o1 == o2) {
cpu_stl_data(env, a2, env->regs[(r1 + 1) & 15]);
if (env->regs[r2] & 0x3) {
if (r2 & 0x3) {
/* flush TLB / ALB */
tlb_flush(env, 1);
}
@ -1154,13 +1040,13 @@ void HELPER(ptlb)(CPUS390XState *env)
}
/* store using real address */
void HELPER(stura)(CPUS390XState *env, uint64_t addr, uint32_t v1)
void HELPER(stura)(CPUS390XState *env, uint64_t addr, uint64_t v1)
{
stw_phys(get_address(env, 0, 0, addr), v1);
stw_phys(get_address(env, 0, 0, addr), (uint32_t)v1);
}
/* load real address */
uint32_t HELPER(lra)(CPUS390XState *env, uint64_t addr, uint32_t r1)
uint64_t HELPER(lra)(CPUS390XState *env, uint64_t addr)
{
uint32_t cc = 0;
int old_exc = env->exception_index;
@ -1184,14 +1070,7 @@ uint32_t HELPER(lra)(CPUS390XState *env, uint64_t addr, uint32_t r1)
}
env->exception_index = old_exc;
if (!(env->psw.mask & PSW_MASK_64)) {
env->regs[r1] = (env->regs[r1] & 0xffffffff00000000ULL) |
(ret & 0xffffffffULL);
} else {
env->regs[r1] = ret;
}
return cc;
env->cc_op = cc;
return ret;
}
#endif

View File

@ -41,7 +41,27 @@
#define HELPER_LOG(x...)
#endif
/* raise an exception */
/* Raise an exception dynamically from a helper function. */
void QEMU_NORETURN runtime_exception(CPUS390XState *env, int excp,
uintptr_t retaddr)
{
int t;
env->exception_index = EXCP_PGM;
env->int_pgm_code = excp;
/* Use the (ultimate) callers address to find the insn that trapped. */
cpu_restore_state(env, retaddr);
/* Advance past the insn. */
t = cpu_ldub_code(env, env->psw.addr);
env->int_pgm_ilen = t = get_ilen(t);
env->psw.addr += 2 * t;
cpu_loop_exit(env);
}
/* Raise an exception statically from a TB. */
void HELPER(exception)(CPUS390XState *env, uint32_t excp)
{
HELPER_LOG("%s: exception %d\n", __func__, excp);
@ -50,7 +70,7 @@ void HELPER(exception)(CPUS390XState *env, uint32_t excp)
}
#ifndef CONFIG_USER_ONLY
void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
void program_interrupt(CPUS390XState *env, uint32_t code, int ilen)
{
qemu_log_mask(CPU_LOG_INT, "program interrupt at %#" PRIx64 "\n",
env->psw.addr);
@ -61,18 +81,16 @@ void program_interrupt(CPUS390XState *env, uint32_t code, int ilc)
#endif
} else {
env->int_pgm_code = code;
env->int_pgm_ilc = ilc;
env->int_pgm_ilen = ilen;
env->exception_index = EXCP_PGM;
cpu_loop_exit(env);
}
}
/* SCLP service call */
uint32_t HELPER(servc)(CPUS390XState *env, uint32_t r1, uint64_t r2)
uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
{
int r;
r = sclp_service_call(r1, r2);
int r = sclp_service_call(r1, r2);
if (r < 0) {
program_interrupt(env, -r, 4);
return 0;
@ -105,38 +123,22 @@ uint64_t HELPER(diag)(CPUS390XState *env, uint32_t num, uint64_t mem,
}
if (r) {
program_interrupt(env, PGM_OPERATION, ILC_LATER_INC);
program_interrupt(env, PGM_OPERATION, ILEN_LATER_INC);
}
return r;
}
/* Store CPU ID */
void HELPER(stidp)(CPUS390XState *env, uint64_t a1)
{
cpu_stq_data(env, a1, env->cpu_num);
}
/* Set Prefix */
void HELPER(spx)(CPUS390XState *env, uint64_t a1)
{
uint32_t prefix;
prefix = cpu_ldl_data(env, a1);
env->psa = prefix & 0xfffff000;
uint32_t prefix = a1 & 0x7fffe000;
env->psa = prefix;
qemu_log("prefix: %#x\n", prefix);
tlb_flush_page(env, 0);
tlb_flush_page(env, TARGET_PAGE_SIZE);
}
/* Set Clock */
uint32_t HELPER(sck)(uint64_t a1)
{
/* XXX not implemented - is it necessary? */
return 0;
}
static inline uint64_t clock_value(CPUS390XState *env)
{
uint64_t time;
@ -148,32 +150,14 @@ static inline uint64_t clock_value(CPUS390XState *env)
}
/* Store Clock */
uint32_t HELPER(stck)(CPUS390XState *env, uint64_t a1)
uint64_t HELPER(stck)(CPUS390XState *env)
{
cpu_stq_data(env, a1, clock_value(env));
return 0;
}
/* Store Clock Extended */
uint32_t HELPER(stcke)(CPUS390XState *env, uint64_t a1)
{
cpu_stb_data(env, a1, 0);
/* basically the same value as stck */
cpu_stq_data(env, a1 + 1, clock_value(env) | env->cpu_num);
/* more fine grained than stck */
cpu_stq_data(env, a1 + 9, 0);
/* XXX programmable fields */
cpu_stw_data(env, a1 + 17, 0);
return 0;
return clock_value(env);
}
/* Set Clock Comparator */
void HELPER(sckc)(CPUS390XState *env, uint64_t a1)
void HELPER(sckc)(CPUS390XState *env, uint64_t time)
{
uint64_t time = cpu_ldq_data(env, a1);
if (time == -1ULL) {
return;
}
@ -187,17 +171,15 @@ void HELPER(sckc)(CPUS390XState *env, uint64_t a1)
}
/* Store Clock Comparator */
void HELPER(stckc)(CPUS390XState *env, uint64_t a1)
uint64_t HELPER(stckc)(CPUS390XState *env)
{
/* XXX implement */
cpu_stq_data(env, a1, 0);
return 0;
}
/* Set CPU Timer */
void HELPER(spt)(CPUS390XState *env, uint64_t a1)
void HELPER(spt)(CPUS390XState *env, uint64_t time)
{
uint64_t time = cpu_ldq_data(env, a1);
if (time == -1ULL) {
return;
}
@ -209,15 +191,15 @@ void HELPER(spt)(CPUS390XState *env, uint64_t a1)
}
/* Store CPU Timer */
void HELPER(stpt)(CPUS390XState *env, uint64_t a1)
uint64_t HELPER(stpt)(CPUS390XState *env)
{
/* XXX implement */
cpu_stq_data(env, a1, 0);
return 0;
}
/* Store System Information */
uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0, uint32_t r0,
uint32_t r1)
uint32_t HELPER(stsi)(CPUS390XState *env, uint64_t a0,
uint64_t r0, uint64_t r1)
{
int cc = 0;
int sel1, sel2;

File diff suppressed because it is too large Load Diff