mirror of https://github.com/xqemu/xqemu.git
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:
commit
837d1f9782
|
@ -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/
|
||||
|
|
173
disas/s390.c
173
disas/s390.c
|
@ -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 =
|
||||
|
|
78
gdbstub.c
78
gdbstub.c
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 */
|
|
@ -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))
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue