mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-04-09 22:01:57 +02:00
4931 lines
220 KiB
C
4931 lines
220 KiB
C
/* OPCODE.H (C) Copyright Jan Jaeger, 2000-2012 */
|
|
/* (C) and others 2013-2023 */
|
|
/* Instruction decoding macros and prototypes */
|
|
/* */
|
|
/* Released under "The Q Public License Version 1" */
|
|
/* (http://www.hercules-390.org/herclic.html) as modifications to */
|
|
/* Hercules. */
|
|
|
|
/* Interpretive Execution - (C) Copyright Jan Jaeger, 1999-2012 */
|
|
/* z/Architecture support - (C) Copyright Jan Jaeger, 1999-2012 */
|
|
|
|
#ifndef _OPCODE_H
|
|
#define _OPCODE_H
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* (delineates ARCH_DEP from non-arch_dep) */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Architecture *INDEPENDENT* macros */
|
|
/*-------------------------------------------------------------------*/
|
|
/* The following macros are defined ONE TIME (due to the above */
|
|
/* "#ifndef _OPCODE_H" guard) and thus are the same for ALL */
|
|
/* build architectures. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* helper macros to define an opcode table instruction function name */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#if defined( _370 )
|
|
#define _GEN370( _ifunc_name ) &s370_ ## _ifunc_name,
|
|
#else
|
|
#define _GEN370( _ifunc_name )
|
|
#endif
|
|
|
|
#if defined( _390 )
|
|
#define _GEN390( _ifunc_name ) &s390_ ## _ifunc_name,
|
|
#else
|
|
#define _GEN390( _ifunc_name )
|
|
#endif
|
|
|
|
#if defined( _900 )
|
|
#define _GEN900( _ifunc_name ) &z900_ ## _ifunc_name,
|
|
#else
|
|
#define _GEN900( _ifunc_name )
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Macros for defining opcode table entries */
|
|
/*-------------------------------------------------------------------*/
|
|
/* */
|
|
/* The below GENx...macros are used to define the NON-archdep master */
|
|
/* opcode table entries in opcode.c. Each entry defines a separate */
|
|
/* pointer to an architecture DEPENDENT instruction function for all */
|
|
/* three of our supported build architectures, as well as a common */
|
|
/* instruction tracing function (based on the instruction's format) */
|
|
/* and a string used during tracing containing the instruction's */
|
|
/* mnemonic and instruction function's name, because each opcode is */
|
|
/* expected to define the same instruction for each architecture if */
|
|
/* that opcode is defined in the given architecture. */
|
|
/* */
|
|
/* That is to say, using the below macros, it is NOT possible to de- */
|
|
/* fine a table entry for a given opcode for an instruction that is */
|
|
/* completely different in one architecture than it is in the other */
|
|
/* architectures. Opcode 'D2' for example, is expected to be the op- */
|
|
/* code for the "MVC" instruction in all three architectures. */
|
|
/* */
|
|
/* With later versions of z/Architecture however, this is not neces- */
|
|
/* sarily always true. In later versions of z/Architecture, IBM has */
|
|
/* begun re-using opcodes for older S/370-only instructions. In such */
|
|
/* type of situations you need to define an architecture DEPENDENT */
|
|
/* opcode table instead, using the new 'AD_GENx...' macros defined */
|
|
/* further below in the architecture-DEPENDENT section of opcode.h */
|
|
/* (which immediately follows the "#endif" for _OPCODE_H). */
|
|
/* */
|
|
/*-------------------------------------------------------------------*/
|
|
/* */
|
|
/* PROGRAMMING NOTE */
|
|
/* */
|
|
/* PROGRAMMING NOTE: the '_ifmt' argument in the below "GENx" macros */
|
|
/* is currently ignored since it is not being used for anything at */
|
|
/* the moment. At some point in the near future however, if things */
|
|
/* work out, it will actually be used as a function call to decode */
|
|
/* the instruction before being dispatched to the actual function */
|
|
/* that executes the instruction, relieving each instruction from */
|
|
/* having to decode the instruction itself each time (as well as */
|
|
/* relieving the instruction 'iprint' (tracing) functions from also */
|
|
/* having to decode the instruction too!) After all, if there are */
|
|
/* 57 instructions defined that use the 'RR' format and 220 defined */
|
|
/* that use the 'RRE' format, etc, why should they each have to do */
|
|
/* the same thing themselves each time? There needs to be a common */
|
|
/* instruction format decoding function that is called before each */
|
|
/* instruction function is ever reached so that all the instruction */
|
|
/* itself has to do is whatever its purpose is. After all, decoding */
|
|
/* an instruction is LOGICALLY part of the instruction decoding and */
|
|
/* dispatching logic, NOT something that each instruction (or each */
|
|
/* 'iprint' tracing function!) should be doing themselves. This is */
|
|
/* what I intend to (hope to) fix at some point in the near future. */
|
|
/* */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define GENx___x___x___ \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ASMFMT_none, \
|
|
(void*) &"?????" "\0" "?" \
|
|
}
|
|
|
|
#define GENx370x___x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
_GEN370( _ifunc_name ) \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define GENx___x390x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
_GEN390( _ifunc_name ) \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define GENx370x390x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
_GEN370( _ifunc_name ) \
|
|
_GEN390( _ifunc_name ) \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define GENx___x___x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
_GEN900( _ifunc_name ) \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define GENx370x___x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
_GEN370( _ifunc_name ) \
|
|
&operation_exception, \
|
|
_GEN900( _ifunc_name ) \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define GENx___x390x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
_GEN390( _ifunc_name ) \
|
|
_GEN900( _ifunc_name ) \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define GENx370x390x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
_GEN370( _ifunc_name ) \
|
|
_GEN390( _ifunc_name ) \
|
|
_GEN900( _ifunc_name ) \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* PROGRAMMING NOTE */
|
|
/*-------------------------------------------------------------------*/
|
|
/* The following set of macros identifies those instructions which */
|
|
/* are a part of the FEATURE_370_EXTENSION backport of some S/390 */
|
|
/* and z/Architecture instructions to System/370 mode (refer to the */
|
|
/* the feat370.h header). All instructions so identified will have */
|
|
/* their instruction generated also for the S/370 architecture mode */
|
|
/* as well, even though such instruction are not formally a part of */
|
|
/* the System/370 architecture. */
|
|
/* */
|
|
/* Whether or not such instructions cause a Program Check Operation */
|
|
/* Exception to occur when executed in S/370 mode is controlled via */
|
|
/* enabling or disabling the 'HERC_370_EXTENSION' archlvl facility. */
|
|
/* */
|
|
/* When the facility is disabled (default), all such instructions */
|
|
/* will properly Program Check (Operation Exception) when attempted */
|
|
/* to be executed in S/370 mode. When the facility enabled however, */
|
|
/* then all such "37X" instructions are instead allowed to execute. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define GENx37Xx390x___ GENx370x390x___
|
|
#define GENx37Xx___x900 GENx370x___x900
|
|
#define GENx37Xx390x900 GENx370x390x900
|
|
|
|
#define AD_GENx37Xx390x___ AD_GENx370x390x___
|
|
#define AD_GENx37Xx___x900 AD_GENx370x___x900
|
|
#define AD_GENx37Xx390x900 AD_GENx370x390x900
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define ILC(_b) ((_b) < 0x40 ? 2 : (_b) < 0xc0 ? 4 : 6)
|
|
|
|
#define REAL_ILC(_regs) \
|
|
(likely(!(_regs)->execflag) ? (_regs)->psw.ilc : (_regs)->exrl ? 6 : 4)
|
|
|
|
#define ILC_FROM_PIID( piid ) (((piid) & 0x00070000) >> 16)
|
|
#define CODE_FROM_PIID( piid ) (((piid) & 0x0000FFFF) )
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Instruction tracing helper function to print the instruction */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define PRINT_INST( _arch_mode, _inst, _prtbuf ) \
|
|
\
|
|
iprint_router_func( (_arch_mode), (_inst), 0, (_prtbuf) )
|
|
|
|
OPCD_DLL_IMPORT int iprint_router_func( int arch_mode, BYTE inst[], char mnemonic[], char* prtbuf );
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Individual instruction counting */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#if defined( OPTION_INSTR_COUNT_AND_TIME )
|
|
|
|
#define BEG_COUNT_INSTR( _inst, _regs ) \
|
|
do \
|
|
{ \
|
|
if (sysblk.icount) \
|
|
{ \
|
|
U64 used; \
|
|
gettimeofday(&sysblk.start_time, NULL); \
|
|
switch ((_inst)[0]) { \
|
|
case 0x01: \
|
|
used = sysblk.imaps.imap01[(_inst)[1]]++; \
|
|
break; \
|
|
case 0xA4: \
|
|
used = sysblk.imaps.imapa4[(_inst)[1]]++; \
|
|
break; \
|
|
case 0xA5: \
|
|
used = sysblk.imaps.imapa5[(_inst)[1] & 0x0F]++; \
|
|
break; \
|
|
case 0xA6: \
|
|
used = sysblk.imaps.imapa6[(_inst)[1]]++; \
|
|
break; \
|
|
case 0xA7: \
|
|
used = sysblk.imaps.imapa7[(_inst)[1] & 0x0F]++; \
|
|
break; \
|
|
case 0xB2: \
|
|
used = sysblk.imaps.imapb2[(_inst)[1]]++; \
|
|
break; \
|
|
case 0xB3: \
|
|
used = sysblk.imaps.imapb3[(_inst)[1]]++; \
|
|
break; \
|
|
case 0xB9: \
|
|
used = sysblk.imaps.imapb9[(_inst)[1]]++; \
|
|
break; \
|
|
case 0xC0: \
|
|
used = sysblk.imaps.imapc0[(_inst)[1] & 0x0F]++; \
|
|
break; \
|
|
case 0xC2: \
|
|
used = sysblk.imaps.imapc2[(_inst)[1] & 0x0F]++; \
|
|
break; \
|
|
case 0xC4: \
|
|
used = sysblk.imaps.imapc4[(_inst)[1] & 0x0F]++; \
|
|
break; \
|
|
case 0xC6: \
|
|
used = sysblk.imaps.imapc6[(_inst)[1] & 0x0F]++; \
|
|
break; \
|
|
case 0xC8: \
|
|
used = sysblk.imaps.imapc8[(_inst)[1] & 0x0F]++; \
|
|
break; \
|
|
case 0xE3: \
|
|
used = sysblk.imaps.imape3[(_inst)[5]]++; \
|
|
break; \
|
|
case 0xE4: \
|
|
used = sysblk.imaps.imape4[(_inst)[1]]++; \
|
|
break; \
|
|
case 0xE5: \
|
|
used = sysblk.imaps.imape5[(_inst)[1]]++; \
|
|
break; \
|
|
case 0xE6: \
|
|
if (sysblk.arch_mode == ARCH_900_IDX) \
|
|
used = sysblk.imaps.imape6[(_inst)[5]]++; \
|
|
else \
|
|
used = sysblk.imaps.imape6[(_inst)[1]]++; \
|
|
break; \
|
|
case 0xE7: \
|
|
used = sysblk.imaps.imape7[(_inst)[5]]++; \
|
|
break; \
|
|
case 0xEB: \
|
|
used = sysblk.imaps.imapeb[(_inst)[5]]++; \
|
|
break; \
|
|
case 0xEC: \
|
|
used = sysblk.imaps.imapec[(_inst)[5]]++; \
|
|
break; \
|
|
case 0xED: \
|
|
used = sysblk.imaps.imaped[(_inst)[5]]++; \
|
|
break; \
|
|
default: \
|
|
used = sysblk.imaps.imapxx[(_inst)[0]]++; \
|
|
} \
|
|
\
|
|
if (!used) \
|
|
{ \
|
|
/* "%s" */ \
|
|
WRMSG( HHC02292, "I", "First use" ); \
|
|
ARCH_DEP( display_inst )( (_regs), (_inst) ); \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
#else // !defined( OPTION_INSTR_COUNT_AND_TIME )
|
|
|
|
#define BEG_COUNT_INSTR(_inst, _regs)
|
|
|
|
#endif // defined( OPTION_INSTR_COUNT_AND_TIME )
|
|
|
|
#if defined( OPTION_INSTR_COUNT_AND_TIME )
|
|
|
|
#define END_COUNT_INSTR(_inst, _regs) \
|
|
do \
|
|
{ \
|
|
if (sysblk.icount) \
|
|
{ \
|
|
struct timeval end_time; \
|
|
struct timeval dur; \
|
|
U64 elapsed_usecs; \
|
|
\
|
|
gettimeofday(&end_time, NULL); \
|
|
timeval_subtract(&sysblk.start_time, &end_time, &dur); \
|
|
elapsed_usecs = (dur.tv_sec * 1000000) + dur.tv_usec; \
|
|
\
|
|
switch ((_inst)[0]) { \
|
|
case 0x01: \
|
|
sysblk.imaps.imap01T[(_inst)[1]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xA4: \
|
|
sysblk.imaps.imapa4T[(_inst)[1]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xA5: \
|
|
sysblk.imaps.imapa5T[(_inst)[1] & 0x0F]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xA6: \
|
|
sysblk.imaps.imapa6T[(_inst)[1]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xA7: \
|
|
sysblk.imaps.imapa7T[(_inst)[1] & 0x0F]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xB2: \
|
|
sysblk.imaps.imapb2T[(_inst)[1]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xB3: \
|
|
sysblk.imaps.imapb3T[(_inst)[1]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xB9: \
|
|
sysblk.imaps.imapb9T[(_inst)[1]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xC0: \
|
|
sysblk.imaps.imapc0T[(_inst)[1] & 0x0F]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xC2: \
|
|
sysblk.imaps.imapc2T[(_inst)[1] & 0x0F]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xC4: \
|
|
sysblk.imaps.imapc4T[(_inst)[1] & 0x0F]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xC6: \
|
|
sysblk.imaps.imapc6T[(_inst)[1] & 0x0F]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xC8: \
|
|
sysblk.imaps.imapc8T[(_inst)[1] & 0x0F]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xE3: \
|
|
sysblk.imaps.imape3T[(_inst)[5]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xE4: \
|
|
sysblk.imaps.imape4T[(_inst)[1]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xE5: \
|
|
sysblk.imaps.imape5T[(_inst)[1]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xE6: \
|
|
sysblk.imaps.imape6T[(_inst)[5]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xE7: \
|
|
sysblk.imaps.imape7T[(_inst)[5]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xEB: \
|
|
sysblk.imaps.imapebT[(_inst)[5]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xEC: \
|
|
sysblk.imaps.imapecT[(_inst)[5]]+=elapsed_usecs; \
|
|
break; \
|
|
case 0xED: \
|
|
sysblk.imaps.imapedT[(_inst)[5]]+=elapsed_usecs; \
|
|
break; \
|
|
default: \
|
|
sysblk.imaps.imapxxT[(_inst)[0]]+=elapsed_usecs; \
|
|
} \
|
|
} \
|
|
} while (0)
|
|
|
|
|
|
#else // !defined( OPTION_INSTR_COUNT_AND_TIME )
|
|
#define END_COUNT_INSTR(_inst, _regs)
|
|
#endif // defined( OPTION_INSTR_COUNT_AND_TIME )
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* SIE macros */
|
|
/* (architecture INDEPENDENT) */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#if defined( _FEATURE_SIE )
|
|
|
|
#define SIE_ACTIVE( _regs ) ((_regs)->sie_active)
|
|
#define SIE_MODE( _regs ) ((_regs)->sie_mode)
|
|
#define SIE_STATE( _regs ) ((_regs)->sie_state)
|
|
|
|
#define SIE_FEAT_BIT_ON( _regs, _byte, _bit ) ((_regs)->siebk->SIE_ ## _byte & SIE_ ## _byte ## _ ## _bit)
|
|
#define SIE_EC_BIT_ON( _regs, _byte, _bit ) ((_regs)->siebk->SIE_ ## _byte & SIE_ ## _byte ## _ ## _bit)
|
|
|
|
#define SIE_FEAT_BIT_OFF( _regs, _byte, _bit ) !SIE_FEAT_BIT_ON( _regs, _byte, _bit )
|
|
#define SIE_EC_BIT_OFF( _regs, _byte, _bit ) !SIE_EC_BIT_ON( _regs, _byte, _bit )
|
|
|
|
#define SIE_STATE_BIT_ON( _regs, _byte, _bit ) (SIE_MODE((_regs)) && SIE_FEAT_BIT_ON( (_regs), _byte, _bit ))
|
|
#define SIE_STATE_BIT_OFF( _regs, _byte, _bit ) (SIE_MODE((_regs)) && SIE_FEAT_BIT_OFF( (_regs), _byte, _bit ))
|
|
|
|
|
|
#define TXF_SIE_INTERCEPT( _regs, _name ) \
|
|
do \
|
|
{ \
|
|
/* Only allow direct execution of TXF instructions \
|
|
if the z/VM host says to allow it. Otherwise let \
|
|
the z/VM host intercept this instruction so it \
|
|
can simulate it, throw a PIC001, or at least be \
|
|
informed that we are executing this instruction. \
|
|
*/ \
|
|
if (1 \
|
|
&& SIE_MODE( (_regs) ) \
|
|
&& SIE_EC_BIT_OFF( (_regs), ECB0, TXF ) \
|
|
) \
|
|
{ \
|
|
if (TXF_TRACING()) \
|
|
{ \
|
|
/* "TXF: %s%02X: SIE: Intercepting \
|
|
%s instruction" */ \
|
|
WRMSG( HHC17715, "D", \
|
|
TXF_CPUAD( _regs ), #_name ); \
|
|
} \
|
|
longjmp( (_regs)->progjmp, SIE_INTERCEPT_INST ); \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
#else // !defined( _FEATURE_SIE )
|
|
|
|
#define SIE_ACTIVE( _regs ) (0)
|
|
#define SIE_MODE( _regs ) (0)
|
|
#define SIE_STATE( _regs ) (0)
|
|
|
|
#define SIE_FEAT_BIT_ON( _regs, _byte, _bit ) (0)
|
|
#define SIE_EC_BIT_ON( _regs, _byte, _bit ) (0)
|
|
#define SIE_STATE_BIT_ON( _regs, _byte, _bit ) (0)
|
|
|
|
#define SIE_FEAT_BIT_OFF( _regs, _byte, _bit ) (1)
|
|
#define SIE_EC_BIT_OFF( _regs, _byte, _bit ) (1)
|
|
#define SIE_STATE_BIT_OFF( _regs, _byte, _bit ) (1)
|
|
|
|
#define TXF_SIE_INTERCEPT( _regs, _name ) /* (do nothing) */
|
|
|
|
#endif // defined( _FEATURE_SIE )
|
|
|
|
#if defined( _FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE )
|
|
#undef MULTIPLE_CONTROLLED_DATA_SPACE
|
|
#define MULTIPLE_CONTROLLED_DATA_SPACE( _regs ) \
|
|
(SIE_FEAT_BIT_ON( (_regs), MX, XC ) && AR_BIT( &(_regs)->psw ))
|
|
#else
|
|
#undef MULTIPLE_CONTROLLED_DATA_SPACE
|
|
#define MULTIPLE_CONTROLLED_DATA_SPACE( _regs ) (0)
|
|
#endif
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Instruction "FOOTPRINT" */
|
|
/*-------------------------------------------------------------------*/
|
|
/* The footprint_buffer option saves a copy of the register context */
|
|
/* every time an instruction is executed. This is for problem */
|
|
/* determination only, as it SEVERELY impacts performance. *JJ */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#if defined( OPTION_FOOTPRINT_BUFFER )
|
|
#define FOOTPRINT(_ip, _regs) \
|
|
do { \
|
|
sysblk.footprregs[(_regs)->cpuad][sysblk.footprptr[(_regs)->cpuad]] = *(_regs); \
|
|
memcpy(&sysblk.footprregs[(_regs)->cpuad][sysblk.footprptr[(_regs)->cpuad]++].inst,(_ip),6); \
|
|
sysblk.footprptr[(_regs)->cpuad] &= OPTION_FOOTPRINT_BUFFER - 1; \
|
|
} while(0)
|
|
#endif
|
|
|
|
#if !defined( FOOTPRINT )
|
|
#define FOOTPRINT(_ip, _regs)
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* CPU Stepping or Tracing */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define TXF_INSTR_TRACING() \
|
|
(sysblk.txf_tracing & TXF_TR_INSTR)
|
|
|
|
|
|
#define TXF_CONSTRAINED_TRANS_INSTR( _regs ) \
|
|
((sysblk.txf_tracing & TXF_TR_C) \
|
|
&& (_regs)->txf_tnd && (_regs)->txf_contran)
|
|
|
|
|
|
#define TXF_UNCONSTRAINED_TRANS_INSTR( _regs ) \
|
|
((sysblk.txf_tracing & TXF_TR_U) \
|
|
&& (_regs)->txf_tnd && !(_regs)->txf_contran)
|
|
|
|
|
|
#define TXF_TRACE_THIS_INSTR( _regs ) \
|
|
(1 \
|
|
&& TXF_TRACE_CPU( _regs ) \
|
|
&& TXF_TRACE_TND( _regs ) \
|
|
&& (0 \
|
|
|| TXF_CONSTRAINED_TRANS_INSTR( _regs ) \
|
|
|| TXF_UNCONSTRAINED_TRANS_INSTR( _regs ) \
|
|
) \
|
|
)
|
|
|
|
|
|
#define _CPU_STEP_OR_TRACE(_breakaddr_or_traceaddr, _regs, _ilc) \
|
|
(0 \
|
|
|| !TXF_INSTR_TRACING() \
|
|
|| TXF_TRACE_THIS_INSTR( _regs ) \
|
|
) \
|
|
&& \
|
|
( \
|
|
(sysblk._breakaddr_or_traceaddr[0] == 0 && \
|
|
sysblk._breakaddr_or_traceaddr[1] == 0) \
|
|
\
|
|
|| (sysblk._breakaddr_or_traceaddr[0] <= \
|
|
sysblk._breakaddr_or_traceaddr[1] \
|
|
\
|
|
&& PSW_IA_FROM_IP((_regs), -(_ilc)) >= \
|
|
sysblk._breakaddr_or_traceaddr[0] \
|
|
&& PSW_IA_FROM_IP((_regs), -(_ilc)) <= \
|
|
sysblk._breakaddr_or_traceaddr[1] \
|
|
) \
|
|
\
|
|
|| (sysblk._breakaddr_or_traceaddr[0] > \
|
|
sysblk._breakaddr_or_traceaddr[1] \
|
|
\
|
|
&& PSW_IA_FROM_IP((_regs), -(_ilc)) >= \
|
|
sysblk._breakaddr_or_traceaddr[1] \
|
|
&& PSW_IA_FROM_IP((_regs), -(_ilc)) <= \
|
|
sysblk._breakaddr_or_traceaddr[0] \
|
|
) \
|
|
) \
|
|
|
|
|
|
#define CPU_STEPPING(_regs, _ilc) \
|
|
(sysblk.instbreak && _CPU_STEP_OR_TRACE(breakaddr,(_regs),(_ilc)))
|
|
|
|
|
|
#define CPU_TRACING(_regs, _ilc) \
|
|
(1 \
|
|
&& sysblk.insttrace \
|
|
&& (_regs)->insttrace \
|
|
&& _CPU_STEP_OR_TRACE( traceaddr, (_regs), (_ilc) ) \
|
|
)
|
|
|
|
|
|
#define CPU_STEPPING_OR_TRACING(_regs, _ilc) \
|
|
( unlikely((_regs)->breakortrace) && \
|
|
(CPU_STEPPING((_regs), (_ilc)) || CPU_TRACING((_regs), (_ilc))) \
|
|
)
|
|
|
|
|
|
#define _CPU_TRACE_ALL \
|
|
(sysblk.traceaddr[0] == 0 && \
|
|
sysblk.traceaddr[1] == 0 && \
|
|
/*sysblk.insttrace*/ insttrace_all())
|
|
|
|
|
|
#define _CPU_STEP_ALL \
|
|
(sysblk.breakaddr[0] == 0 && \
|
|
sysblk.breakaddr[1] == 0 && \
|
|
sysblk.instbreak)
|
|
|
|
|
|
#define CPU_STEPPING_OR_TRACING_ALL (_CPU_STEP_ALL || _CPU_TRACE_ALL)
|
|
|
|
|
|
#define PROCESS_TRACE( _regs, _ip, _goto ) \
|
|
do \
|
|
{ \
|
|
/* If stepping or tracing, trace this instruction */ \
|
|
if ((_regs)->breakortrace) \
|
|
{ \
|
|
ARCH_DEP( process_trace )( (_regs), (_ip) ); \
|
|
\
|
|
/* If the aie was invalidated, re-fetch the instruction. \
|
|
Another CPU executing e.g. a IPTE instruction during \
|
|
instruction stepping while process_trace was waiting \
|
|
for the user to press the enter key can allow this to \
|
|
occur. Otherwise it is impossible to occur. */ \
|
|
if (1 \
|
|
&& (_regs)->stepping \
|
|
&& !VALID_AIE( _regs ) \
|
|
) \
|
|
{ \
|
|
/* "Processor %s%02X: aie invalidated; instruction refetched" */ \
|
|
WRMSG( HHC00835, "W", PTYPSTR( (_regs)->cpuad ), (_regs)->cpuad ); \
|
|
goto _goto; \
|
|
} \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Simple helper macro that instructions can use */
|
|
/* to force an immediate check for interrupts. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define RETURN_INTCHECK(_regs) \
|
|
longjmp((_regs)->progjmp, SIE_NO_INTERCEPT)
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Instruction validity checking */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define ODD_CHECK(_r, _regs) \
|
|
if( (_r) & 1 ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
#define ODD2_CHECK(_r1, _r2, _regs) \
|
|
if( ((_r1) & 1) || ((_r2) & 1) ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
#define HW_CHECK(_value, _regs) \
|
|
if( (_value) & 1 ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
#define FW_CHECK(_value, _regs) \
|
|
if( (_value) & 3 ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
#define DW_CHECK(_value, _regs) \
|
|
if( (_value) & 7 ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
#define QW_CHECK(_value, _regs) \
|
|
if( (_value) & 15 ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
/* Program check if m is not 0, 1, or 4 to 7 */
|
|
#define HFPM_CHECK(_m, _regs) \
|
|
if (((_m) == 2) || ((_m) == 3) || ((_m) & 8)) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
#define PRIV_CHECK(_regs) \
|
|
if( PROBSTATE(&(_regs)->psw) ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_PRIVILEGED_OPERATION_EXCEPTION)
|
|
|
|
/* Program check if r is not 0,1,4,5,8,9,12, or 13 (designating
|
|
the lower-numbered register of a floating-point register pair) */
|
|
#define BFPREGPAIR_CHECK(_r, _regs) \
|
|
if( ((_r) & 2) ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
/* Program check if r1 and r2 are not both 0,1,4,5,8,9,12, or 13
|
|
(lower-numbered register of a floating-point register pair) */
|
|
#define BFPREGPAIR2_CHECK(_r1, _r2, _regs) \
|
|
if( ((_r1) & 2) || ((_r2) & 2) ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
/* Program check if r is not 0,1,4,5,8,9,12, or 13 (designating
|
|
the lower-numbered register of a floating-point register pair) */
|
|
#define DFPREGPAIR_CHECK(_r, _regs) \
|
|
if( ((_r) & 2) ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
/* Program check if r1 and r2 are not both 0,1,4,5,8,9,12, or 13
|
|
(lower-numbered register of a floating-point register pair) */
|
|
#define DFPREGPAIR2_CHECK(_r1, _r2, _regs) \
|
|
if( ((_r1) & 2) || ((_r2) & 2) ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
/* Program check if r1, r2, r3 are not all 0,1,4,5,8,9,12, or 13
|
|
(lower-numbered register of a floating-point register pair) */
|
|
#define DFPREGPAIR3_CHECK(_r1, _r2, _r3, _regs) \
|
|
if( ((_r1) & 2) || ((_r2) & 2) || ((_r3) & 2) ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION)
|
|
|
|
#define SSID_CHECK(_regs) \
|
|
if((!((_regs)->GR_LHH(1) & 0x0001)) \
|
|
|| (_regs)->GR_LHH(1) > (0x0001|(FEATURE_LCSS_MAX-1))) \
|
|
(_regs)->program_interrupt( (_regs), PGM_OPERAND_EXCEPTION)
|
|
|
|
#if defined( _FEATURE_S370_S390_VECTOR_FACILITY )
|
|
|
|
#ifndef _VFDEFS
|
|
#define _VFDEFS
|
|
#define VOP_CHECK( _regs ) if (!((_regs)->CR(0) & CR0_VOP) || !(_regs)->vf->online) \
|
|
(_regs)->program_interrupt( (_regs), PGM_VECTOR_OPERATION_EXCEPTION )
|
|
#define VR_INUSE( _vr, _regs ) ((_regs)->vf->vsr & (VSR_VIU0 >> ((_vr) >> 1)))
|
|
#define VR_CHANGED( _vr, _regs ) ((_regs)->vf->vsr & (VSR_VCH0 >> ((_vr) >> 1)))
|
|
#define SET_VR_INUSE( _vr, _regs ) (_regs)->vf->vsr |= (VSR_VIU0 >> ((_vr) >> 1))
|
|
#define SET_VR_CHANGED( _vr, _regs ) (_regs)->vf->vsr |= (VSR_VCH0 >> ((_vr) >> 1))
|
|
#define RESET_VR_INUSE( _vr, _regs ) (_regs)->vf->vsr &= ~(VSR_VIU0 >> ((_vr) >> 1))
|
|
#define RESET_VR_CHANGED( _vr, _regs ) (_regs)->vf->vsr &= ~(VSR_VCH0 >> ((_vr) >> 1))
|
|
#define VMR_SET( _section, _regs ) ((_regs)->vf->vmr[(_section) >> 3] & (0x80 >> ((_section) & 7)))
|
|
#define MASK_MODE( _regs ) ((_regs)->vf->vsr & VSR_M)
|
|
#define VECTOR_COUNT( _regs ) (((_regs)->vf->vsr & VSR_VCT) >> 32)
|
|
#define VECTOR_IX( _regs ) (((_regs)->vf->vsr & VSR_VIX) >> 16)
|
|
#endif /* _VFDEFS */
|
|
#endif /* defined( _FEATURE_S370_S390_VECTOR_FACILITY ) */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Device IOID / SSID / LCSS macros */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define IOID_TO_SSID( _ioid ) ((_ioid) >> 16)
|
|
#define IOID_TO_LCSS( _ioid ) ((_ioid) >> 17)
|
|
#define SSID_TO_LCSS( _ssid ) ((_ssid) >> 1 )
|
|
#define LCSS_TO_SSID( _lcss ) (((_lcss) << 1 ) | 1)
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Virtual Architecture Level Set Facility */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define FACILITY_ENABLED(_faci, _regs) \
|
|
(((_regs)->facility_list [ ((STFL_ ## _faci)/8) ]) & (0x80 >> ((STFL_ ## _faci) % 8)))
|
|
|
|
#define FACILITY_ENABLED_DEV(_faci) \
|
|
((sysblk.facility_list[ sysblk.arch_mode ][ ((STFL_ ## _faci)/8) ]) & (0x80 >> ((STFL_ ## _faci) % 8)))
|
|
|
|
#define FACILITY_ENABLED_ARCH( _faci, _arch ) \
|
|
((sysblk.facility_list[ (_arch) ][ ((STFL_ ## _faci)/8) ]) & (0x80 >> ((STFL_ ## _faci) % 8)))
|
|
|
|
#define FACILITY_CHECK(_faci, _regs) \
|
|
do { \
|
|
if(!FACILITY_ENABLED( _faci, _regs ) ) \
|
|
(_regs)->program_interrupt( (_regs), PGM_OPERATION_EXCEPTION); \
|
|
} while (0)
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* PER range checking */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define PER_RANGE_CHECK(_addr, _low, _high) \
|
|
( (((_high) & MAXADDRESS) >= ((_low) & MAXADDRESS)) ? \
|
|
(((_addr) >= ((_low) & MAXADDRESS)) && (_addr) <= ((_high) & MAXADDRESS)) : \
|
|
(((_addr) >= ((_low) & MAXADDRESS)) || (_addr) <= ((_high) & MAXADDRESS)) )
|
|
|
|
#define PER_RANGE_CHECK2(_addr1, _addr2, _low, _high) \
|
|
( (((_high) & MAXADDRESS) >= ((_low) & MAXADDRESS)) ? \
|
|
(((_addr1) >= ((_low) & MAXADDRESS)) && (_addr1) <= ((_high) & MAXADDRESS)) || \
|
|
(((_addr2) >= ((_low) & MAXADDRESS)) && (_addr2) <= ((_high) & MAXADDRESS)) || \
|
|
(((_addr1) <= ((_low) & MAXADDRESS)) && (_addr2) >= ((_high) & MAXADDRESS)) : \
|
|
(((_addr2) >= ((_low) & MAXADDRESS)) || (_addr1) <= ((_high) & MAXADDRESS)) )
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Byte swapping macros */
|
|
/*-------------------------------------------------------------------*/
|
|
/* The "CSWAPxx()" macros CONDITIONALLY swap the endianness of the */
|
|
/* given argument depending on the endianness of the current host, */
|
|
/* much like the "htonl()" networking API functions. If this build */
|
|
/* of Hercules is for running on a big endian host, then CSWAPxx() */
|
|
/* will do absolutely nothing since the argument should already be */
|
|
/* in big endian format. If this build of Hercules is for running */
|
|
/* on a little endian host however, it will perform the byte swap */
|
|
/* so that the result is a big endian value (since z/Architecture */
|
|
/* is big endian). */
|
|
/* */
|
|
/* The SWAPxx() macros however, UNCONDITIONALLY swap the endianness */
|
|
/* of the specified value REGARDLESS of the endianness Hercules was */
|
|
/* built for or the endianness of the host it is running on. It is */
|
|
/* designed for situations such as what might exist when a number */
|
|
/* is read or written to/from disk in a format different from the */
|
|
/* format of the Hercules build or the host it is running on (such */
|
|
/* as what occurs with Hercules's emulated dasd files). In such a */
|
|
/* situation the device driver detects the endianness of the system */
|
|
/* it is running on differs from the endianness that the DASD file */
|
|
/* was written in, thereby requiring it to *UNCONDITIONALLY* swap */
|
|
/* the value that was read from disk, REGARDLESS of the endianness */
|
|
/* of the Hercules build or the host it is currently running on. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#ifdef WORDS_BIGENDIAN // BE (BIG Endian) host...
|
|
|
|
// (_x) = Z guest BE format, result thus ALWAYS BE (BIG Endian format
|
|
|
|
#define CSWAP16(_x) (_x) // (result ALWAYS BIG Endian)
|
|
#define CSWAP32(_x) (_x) // (result ALWAYS BIG Endian)
|
|
#define CSWAP64(_x) (_x) // (result ALWAYS BIG Endian)
|
|
#define CSWAP128(_x) (_x) // (result ALWAYS BIG Endian)
|
|
|
|
#else // LE (Little Endian) host...
|
|
|
|
// (_x) = Z guest BE format, result thus ALWAYS LE (Little Endian)...
|
|
|
|
#define CSWAP16(_x) bswap_16(_x) // (result ALWAYS Little Endian)
|
|
#define CSWAP32(_x) bswap_32(_x) // (result ALWAYS Little Endian)
|
|
#define CSWAP64(_x) bswap_64(_x) // (result ALWAYS Little Endian)
|
|
#define CSWAP128(_x) bswap_128(_x) // (result ALWAYS Little Endian)
|
|
|
|
#endif
|
|
|
|
#define SWAP16(_x) bswap_16(_x) // (result OPPOSITE of input)
|
|
#define SWAP32(_x) bswap_32(_x) // (result OPPOSITE of input)
|
|
#define SWAP64(_x) bswap_64(_x) // (result OPPOSITE of input)
|
|
#define SWAP128(_x) bswap_128(_x) // (result OPPOSITE of input)
|
|
|
|
#define SWAP_OFF_T(o) (sizeof(o) <= 4 ? SWAP32((U32)o) : SWAP64(o))
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Guest storage FETCH/STORE macros */
|
|
/*-------------------------------------------------------------------*/
|
|
/* The following macros fetch a value from emulated guest storage */
|
|
/* into a local work variable or store a local work variable into */
|
|
/* emulated guest storage, performing a CONDITIONAL swap in between */
|
|
/* (via the "CSWAPxx()" macro) to ensure the value placed into guest */
|
|
/* storage is always big endian or that the local work variable is */
|
|
/* always in the expected big or little endian format (depending on */
|
|
/* which endianness Hercules was built for). */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define FETCH_HW( _val, _stor ) (_val) = fetch_hw( _stor )
|
|
#define FETCH_FW( _val, _stor ) (_val) = fetch_fw( _stor )
|
|
#define FETCH_F3( _val, _stor ) (_val) = fetch_f3( _stor )
|
|
#define FETCH_DW( _val, _stor ) (_val) = fetch_dw( _stor )
|
|
#define FETCH_QW( _val, _stor ) (_val) = fetch_qw( _stor )
|
|
|
|
#define STORE_HW( _stor, _val ) store_hw( _stor, _val )
|
|
#define STORE_FW( _stor, _val ) store_fw( _stor, _val )
|
|
#define STORE_F3( _stor, _val ) store_f3( _stor, _val )
|
|
#define STORE_DW( _stor, _val ) store_dw( _stor, _val )
|
|
#define STORE_QW( _stor, _val ) store_qw( _stor, _val )
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* CKD/CCKD header field FETCH/STORE macros */
|
|
/*-------------------------------------------------------------------*/
|
|
/* The following macros fetch a value from a CCKD dasd header field */
|
|
/* into a local work variable or store a local work variable into */
|
|
/* a CCKD dasd header field (e.g. CKD_DEVHDR, CCKD_DEVHDR) doing an */
|
|
/* UNCONDITIONAL "SWAPxx()" in between to ensure the numeric value */
|
|
/* stored into, or fetched from, the CCKD header field is always in */
|
|
/* LITTLE endian format, accomplishing the complete opposite of the */
|
|
/* above "FETCH_FW/STORE_FW/etc" macros. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define FETCH_LE_HW( _val, _stor ) (_val) = SWAP16( fetch_hw( _stor ))
|
|
#define FETCH_LE_FW( _val, _stor ) (_val) = SWAP32( fetch_fw( _stor ))
|
|
#define FETCH_LE_DW( _val, _stor ) (_val) = SWAP64( fetch_dw( _stor ))
|
|
|
|
#define STORE_LE_HW( _stor, _val ) store_hw( _stor, SWAP16( _val ))
|
|
#define STORE_LE_FW( _stor, _val ) store_fw( _stor, SWAP32( _val ))
|
|
#define STORE_LE_DW( _stor, _val ) store_dw( _stor, SWAP64( _val ))
|
|
|
|
#include "machdep.h"
|
|
|
|
#endif /* !defined( _OPCODE_H ) */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* (delineates ARCH_DEP from non-arch_dep) */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Architecture *DEPENDENT* macros */
|
|
/*-------------------------------------------------------------------*/
|
|
/* The below macros (due to being outside of the above "#endif" */
|
|
/* for "_OPCODE_H") are undef'ed and then re-defined differently */
|
|
/* for each subsequent new build architecture. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Macros for defining ARCH_DEP master opcode table entries */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#undef AD_GENx___x___x___
|
|
#undef AD_GENx370x___x___
|
|
#undef AD_GENx___x390x___
|
|
#undef AD_GENx370x390x___
|
|
#undef AD_GENx___x___x900
|
|
#undef AD_GENx370x___x900
|
|
#undef AD_GENx___x390x900
|
|
#undef AD_GENx370x390x900
|
|
|
|
#if __GEN_ARCH == 370
|
|
|
|
#define AD_GENx___x___x___ \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ASMFMT_none, \
|
|
(void*) &"?????" "\0" "?" \
|
|
}
|
|
|
|
#define AD_GENx370x___x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
_GEN370( _ifunc_name ) \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx___x390x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx370x390x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
_GEN370( _ifunc_name ) \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx___x___x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx370x___x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
_GEN370( _ifunc_name ) \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx___x390x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx370x390x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
_GEN370( _ifunc_name ) \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#elif __GEN_ARCH == 390
|
|
|
|
#define AD_GENx___x___x___ \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ASMFMT_none, \
|
|
(void*) &"?????" "\0" "?" \
|
|
}
|
|
|
|
#define AD_GENx370x___x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx___x390x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
_GEN390( _ifunc_name ) \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx370x390x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
_GEN390( _ifunc_name ) \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx___x___x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx370x___x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx___x390x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
_GEN390( _ifunc_name ) \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx370x390x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
_GEN390( _ifunc_name ) \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#elif __GEN_ARCH == 900
|
|
|
|
#define AD_GENx___x___x___ \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ASMFMT_none, \
|
|
(void*) &"?????" "\0" "?" \
|
|
}
|
|
|
|
#define AD_GENx370x___x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx___x390x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx370x390x___( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx___x___x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
_GEN900( _ifunc_name ) \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx370x___x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
_GEN900( _ifunc_name ) \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx___x390x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
_GEN900( _ifunc_name ) \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#define AD_GENx370x390x900( _mnemonic, _ifmt, _asmfmt, _ifunc_name ) \
|
|
{ \
|
|
&operation_exception, \
|
|
&operation_exception, \
|
|
_GEN900( _ifunc_name ) \
|
|
(void*) &iprint_ ## _asmfmt, \
|
|
(void*) & _mnemonic "\0" #_ifunc_name \
|
|
}
|
|
|
|
#else
|
|
#error HUH?!
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* PSW Instruction Address macros */
|
|
/*-------------------------------------------------------------------*/
|
|
// The _IA_FROM_IP primary helper macro returns a raw virtual PSW
|
|
// 'IA' value corresponding to where an offset mainstor 'ip' points,
|
|
// i.e. psw.ia <== aiv + ((ip + offset) - aip).
|
|
|
|
#undef _IA_FROM_IP
|
|
#define _IA_FROM_IP( _aiv, _regs, _offset ) \
|
|
( \
|
|
(_regs)->_aiv \
|
|
+ ((uintptr_t)(_regs)->ip - (uintptr_t)(_regs)->aip) \
|
|
+ (_offset) \
|
|
)
|
|
|
|
//---------------------------------------------------------------------
|
|
// The generic PSW_IA_FROM_IP macro returns a PSW 'IA' as VADR value
|
|
// corresponding to where regs 'ip' is pointing plus a passed offset,
|
|
// with the resulting PSW 'IA' value masked with ADDRESS_MAXWRAP.
|
|
|
|
#undef PSW_IA_FROM_IP
|
|
#define PSW_IA_FROM_IP( _regs, _offset ) \
|
|
\
|
|
((VADR)(_IA_FROM_IP( AIV, (_regs), (_offset)) & ADDRESS_MAXWRAP( _regs )))
|
|
|
|
//---------------------------------------------------------------------
|
|
// The next three macros are minor architectural variations of the
|
|
// above PSW_IA_FROM_IP macro that return a PSW 'IA' value matching
|
|
// where 'ip' plus a passed offset is pointing. The only difference is
|
|
// each are specific to the implied architecture, none of them cast
|
|
// the result to VADR, and only PSW_IA24 applies an addressing mask.
|
|
|
|
#undef PSW_IA64
|
|
#define PSW_IA64( _regs, _offset ) \
|
|
\
|
|
(_IA_FROM_IP( AIV_G, (_regs), (_offset)))
|
|
|
|
#undef PSW_IA31
|
|
#define PSW_IA31( _regs, _offset ) \
|
|
\
|
|
(_IA_FROM_IP( AIV_L, (_regs), (_offset)))
|
|
|
|
#undef PSW_IA24
|
|
#define PSW_IA24( _regs, _offset ) \
|
|
\
|
|
(_IA_FROM_IP( AIV_L, (_regs), (_offset)) & AMASK24)
|
|
|
|
//---------------------------------------------------------------------
|
|
// The PSEUDO_INVALID_AIE value is used whenever you wish to force
|
|
// a break in normal instruction processing and cause the 'instfetch'
|
|
// function to be called to perform a full address translation and
|
|
// fetch of the next instruction. It is mostly used by instruction
|
|
// stepping and tracing logic as well as by the SUCCESS_BRANCH macro
|
|
// when the target of the branch is in a different mainstor page.
|
|
// The "INVALID_AIE" value is used only by the INVALIDATE_AIA and
|
|
// INVALIDATE_AIA_MAIN macros to ALSO to prevent any unwanted PSW
|
|
// updating by short circuiting both the MAYBE_SET_PSW_IA_FROM_IP and
|
|
// SET_PSW_IA_AND_MAYBE_IP macros. The "PSEUDO_INVALID_AIE" value
|
|
// also forces instfetch to be called but additionally allows both
|
|
// the MAYBE_SET_PSW_IA_FROM_IP and SET_PSW_IA_AND_MAYBE_IP macros
|
|
// to continue behaving normally.
|
|
|
|
#define INVALID_AIE (NULL)
|
|
#define PSEUDO_INVALID_AIE ((BYTE*) 1)
|
|
|
|
#undef VALID_AIE
|
|
#define VALID_AIE( _regs ) ((_regs)->aie != INVALID_AIE)
|
|
|
|
//---------------------------------------------------------------------
|
|
// The MAYBE_SET_PSW_IA_FROM_IP macro (notice the 'MAYBE' and 'SET'
|
|
// in its name) CONDITIONALLY sets the virtual psw 'IA' value to point
|
|
// to the same corresponding place as where the current mainstor 'ip'
|
|
// currently points (with no offset), but does so IF AND ONLY IF the
|
|
// 'aie' value is still valid. Otherwise it does absolutely nothing.
|
|
|
|
#undef MAYBE_SET_PSW_IA_FROM_IP
|
|
#define MAYBE_SET_PSW_IA_FROM_IP( _regs ) \
|
|
do \
|
|
{ \
|
|
if (VALID_AIE( _regs )) \
|
|
(_regs)->psw.IA = PSW_IA_FROM_IP( (_regs), 0 ); \
|
|
} \
|
|
while (0)
|
|
|
|
//---------------------------------------------------------------------
|
|
// The SET_PSW_IA_AND_MAYBE_IP macro (notice the 'MAYBE' in its name)
|
|
// performs the opposite of the above MAYBE_SET_PSW_IA_FROM_IP macro:
|
|
// it sets the mainstor 'ip' to the same corresponding place as where
|
|
// the passed virtual psw 'IA' value points. It first UNCONDITIONALLY
|
|
// SETS the PSW IA to the passed value and then MAYBE also sets the
|
|
// 'ip' to the same corresponding place in mainstor, but it ONLY does
|
|
// so IF AND ONLY IF the updated 'ia' value still points within the
|
|
// same virtual page. If it doesn't, then the 'aie' value is set to
|
|
// NULL to force a full 'instfetch' which then calculates a new 'ip',
|
|
// 'aie' and 'aip' value on the next instruction fetch.
|
|
|
|
#undef SET_PSW_IA_AND_MAYBE_IP
|
|
#define SET_PSW_IA_AND_MAYBE_IP( _regs, _ia ) \
|
|
do \
|
|
{ \
|
|
(_regs)->psw.IA = (_ia) & ADDRESS_MAXWRAP( _regs ); \
|
|
\
|
|
if (VALID_AIE( _regs )) \
|
|
{ \
|
|
if ((_regs)->AIV == ((_regs)->psw.IA & (PAGEFRAME_PAGEMASK|1))) \
|
|
(_regs)->ip = _PSW_IA_MAIN( (_regs), (_regs)->psw.IA ); \
|
|
else \
|
|
(_regs)->aie = INVALID_AIE; \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
//---------------------------------------------------------------------
|
|
// The INST_UPDATE_PSW macro sets the psw ILC to the passed value and
|
|
// bumps the regs->ip instruction pointer by the passed _len value,
|
|
// BUT ONLY IF the passed value is non-zero.
|
|
//
|
|
// It is typically used by the instruction decoder macros to set the
|
|
// ilc for the instruction just decoded and to then bump the 'ip' to
|
|
// the next sequential instruction.
|
|
//
|
|
// Normally '_len' and '_ilc' are the same value (being the length
|
|
// of the instruction being decoded). The reason they are passed as
|
|
// separate values however is to allow for branch instructions to
|
|
// set the ilc value while at the same time NOT bumping the 'ip'
|
|
// since they don't know yet if the branch will be taken or not.
|
|
// If it is, they call the SUCCESSFUL_BRANCH macro. If not, they
|
|
// call the INST_UPDATE_PSW to go on to the next instruction.
|
|
|
|
#undef INST_UPDATE_PSW
|
|
#define INST_UPDATE_PSW( _regs, _len, _ilc ) \
|
|
do \
|
|
{ \
|
|
(_regs)->ip += (_len); \
|
|
if (_ilc) \
|
|
(_regs)->psw.ilc = (_ilc); \
|
|
} \
|
|
while(0)
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Accelerator for Instruction Addresses */
|
|
/*-------------------------------------------------------------------*/
|
|
/* The AIA is a term used to refer to the set of REGS fields that */
|
|
/* together control instruction execution. It consists if the 'ip', */
|
|
/* 'aip', 'aie' and 'aiv' fields. The 'ip' field of course is the */
|
|
/* mainstor instruction pointer. The 'aip' is the page address of */
|
|
/* the mainstor page associated with the 'ip'. The 'aiv' field is */
|
|
/* the guest virtual address of the page corresponding to the aip. */
|
|
/* The 'aie' is the "logical end" of the 'aip'. It is the highest */
|
|
/* mainstor 'ip' address that we can safely DIRECTLY fetch the next */
|
|
/* instruction from. Once the 'ip' reaches the 'aie', instruction */
|
|
/* fetching is forced to do a call to the "instfetch" function to */
|
|
/* perform full translation of the address of the next instruction, */
|
|
/* recalculating new 'ip', 'aip', 'aiv' and 'aie' values which can */
|
|
/* then be used again for DIRECT instruction fetching. This allows */
|
|
/* us to "accelerate" instruction fetching since we don't have to */
|
|
/* go through full address translation for each instruction fetch. */
|
|
/* We only need to do so when the instruction being fetched crosses */
|
|
/* over into a new page. That's the 'aie'. It is set to the end of */
|
|
/* the 'aip' page minus 5 bytes. As long as 'ip' is LESS than aie, */
|
|
/* we know we can safely fetch the next instruction from that same */
|
|
/* mainstor page. Otherwise we need to do a full instfetch. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
// The INVALIDATE_AIA macro essentially renders all AIA fields as
|
|
// being invalid, thereby forcing a full instfetch to be performed.
|
|
// It first ensures that the IA (address of the next instruction)
|
|
// in the guest PSW structure matches where the current regs 'ip'
|
|
// instruction pointer is pointing, and then "invalidates" all AIA
|
|
// fields by setting the 'aie' value to NULL, thereby forcing the
|
|
// next instruction fetch to call the 'instfetch' function.
|
|
|
|
#undef INVALIDATE_AIA
|
|
#define INVALIDATE_AIA( _regs ) \
|
|
do \
|
|
{ \
|
|
if (VALID_AIE( _regs )) \
|
|
{ \
|
|
(_regs)->psw.IA = PSW_IA_FROM_IP( (_regs), 0 ); \
|
|
(_regs)->aie = INVALID_AIE; \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
//---------------------------------------------------------------------
|
|
// The INVALIDATE_AIA_MAIN macro performs a conditional invalidation
|
|
// of the AIA, but if and ONLY if the passed mainstor address matches
|
|
// the 'aip'. It is used (e.g. the "invalidate_tlbe" function called
|
|
// by the STORKEY_INVALIDATE macro) to invalidate the AIA whenever a
|
|
// DAT page table entry is invalidated that happens to correspond to
|
|
// the mainstor page we're currently fetching instructions from. It
|
|
// first updates the psw IA to match the current instruction address
|
|
// and then sets the 'aie' to NULL to force a full instruction fetch.
|
|
|
|
#undef INVALIDATE_AIA_MAIN
|
|
#define INVALIDATE_AIA_MAIN( _regs, _main ) \
|
|
do \
|
|
{ \
|
|
if (VALID_AIE( _regs ) && \
|
|
(((uintptr_t)(_main)) & PAGEFRAME_PAGEMASK) == \
|
|
((uintptr_t)(_regs)->aip) \
|
|
) \
|
|
{ \
|
|
(_regs)->psw.IA = PSW_IA_FROM_IP( (_regs), 0 ); \
|
|
(_regs)->aie = INVALID_AIE; \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
//---------------------------------------------------------------------
|
|
// The _PSW_IA_MAIN helper macro returns the mainstor address
|
|
// corresponding to a given guest virtual address. NOTE CAREFULLY
|
|
// that it PRESUMES the virtual address that is passed is within the
|
|
// same mainstor page as we're currently fetching instructions from!
|
|
|
|
#undef _PSW_IA_MAIN
|
|
#define _PSW_IA_MAIN( _regs, _addr ) \
|
|
( \
|
|
(BYTE*) \
|
|
( \
|
|
(uintptr_t)(_regs)->aip \
|
|
| \
|
|
(uintptr_t)((_addr) & PAGEFRAME_BYTEMASK) \
|
|
) \
|
|
)
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Instruction fetching */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
// The _VALID_IP helper macro is used only by the INSTRUCTION_FETCH
|
|
// macro and returns either true/false indicating whether the current
|
|
// instruction pointer is still valid or not (so INSTRUCTION_FETCH
|
|
// can know whether to call the instfetch' function or not). It does
|
|
// this by verifying regs->ip is either still less than regs->aie,
|
|
// or for the 'exec' case, that the mainstor address corresponding
|
|
// to regs->ET (the target of the execute instruction) is still less
|
|
// than regs->aie. It determines the mainstor address of regs->ET
|
|
// via the _PSW_IA_MAIN helper macro.
|
|
|
|
#undef _VALID_IP
|
|
#define _VALID_IP( _regs, _exec ) \
|
|
( \
|
|
/* Instr NOT being EXecuted and instr ptr in same page */ \
|
|
(1 \
|
|
&& !(_exec) \
|
|
&& (_regs)->ip < (_regs)->aie \
|
|
) \
|
|
|| \
|
|
/* Instr IS being EXecuted and instr ptr in same page */ \
|
|
(1 \
|
|
&& (_exec) \
|
|
/* Execute target in same virtual page? */ \
|
|
&& ((_regs)->ET & (PAGEFRAME_PAGEMASK|0x01)) == (_regs)->AIV \
|
|
/* Execute target in same mainstor page? */ \
|
|
&& _PSW_IA_MAIN( (_regs), (_regs)->ET ) < (_regs)->aie \
|
|
) \
|
|
)
|
|
|
|
//---------------------------------------------------------------------
|
|
// The INSTRUCTION_FETCH macro returns a mainstor 'ip' pointer
|
|
// pointing to the next instruction to be executed. It either
|
|
// returns regs->ip directly (or for the 'exec' case, the
|
|
// corresponding mainstor address of the instruction being
|
|
// executed), or else calls the 'instfetch' function to calculate
|
|
// a new set of AIA values (ip, aie, aip and aiv).
|
|
|
|
#undef INSTRUCTION_FETCH
|
|
#define INSTRUCTION_FETCH( _regs, _exec ) \
|
|
\
|
|
/* If ip still valid, use current ip or target of executed instr */ \
|
|
likely( _VALID_IP( (_regs), (_exec) )) ? \
|
|
( \
|
|
(_exec) ? \
|
|
_PSW_IA_MAIN( (_regs), (_regs)->ET ) \
|
|
: \
|
|
(_regs)->ip \
|
|
) \
|
|
/* Else do a full instruction fetch (which updates the AIA too) */ \
|
|
: ARCH_DEP( instfetch )( (_regs), (_exec) )
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Instruction execution */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#if !defined( FEATURE_073_TRANSACT_EXEC_FACILITY )
|
|
|
|
#undef ABORT_TRANS /* (nothing) */
|
|
#define ABORT_TRANS( _regs, _retry, _tac ) /* (nothing) */
|
|
|
|
#undef TXF_INSTRADDR_CONSTRAINT /* (nothing) */
|
|
#define TXF_INSTRADDR_CONSTRAINT( _regs ) /* (nothing) */
|
|
|
|
#undef TXF_INSTRCOUNT_CONSTRAINT /* (nothing) */
|
|
#define TXF_INSTRCOUNT_CONSTRAINT( _ip, _regs ) /* (nothing) */
|
|
|
|
#undef TXF_RAND_ABORT_CONSTRAINT /* (nothing) */
|
|
#define TXF_RAND_ABORT_CONSTRAINT( _regs ) /* (nothing) */
|
|
|
|
#undef CHECK_TXF_CONSTRAINTS /* (nothing) */
|
|
#define CHECK_TXF_CONSTRAINTS( _ip, _regs ) /* (nothing) */
|
|
|
|
#else /* defined( FEATURE_073_TRANSACT_EXEC_FACILITY ) */
|
|
|
|
#undef ABORT_TRANS
|
|
#define ABORT_TRANS( _regs, _retry, _tac ) \
|
|
ARCH_DEP( abort_transaction )( (_regs), (_retry), (_tac), PTT_LOC )
|
|
|
|
#undef TXF_INSTRADDR_CONSTRAINT
|
|
#define TXF_INSTRADDR_CONSTRAINT( _regs ) \
|
|
do { \
|
|
if (1 \
|
|
&& (_regs)->txf_contran \
|
|
&& (_regs)->ip >= (_regs)->txf_aie \
|
|
) \
|
|
{ \
|
|
(_regs)->txf_why |= TXF_WHY_INSTRADDR; \
|
|
ABORT_TRANS( (_regs), -ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#undef TXF_INSTRCOUNT_CONSTRAINT
|
|
#define TXF_INSTRCOUNT_CONSTRAINT( _ip, _regs ) \
|
|
do { \
|
|
if (1 \
|
|
&& (_regs)->txf_contran \
|
|
&& (_regs)->txf_instctr > MAX_TXF_CONTRAN_INSTR \
|
|
&& memcmp( (_ip), "\xb2\xf8", 2 ) != 0 \
|
|
) \
|
|
{ \
|
|
(_regs)->txf_why |= TXF_WHY_INSTRCOUNT; \
|
|
ABORT_TRANS( (_regs), -ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#undef TXF_RAND_ABORT_CONSTRAINT
|
|
#define TXF_RAND_ABORT_CONSTRAINT( _regs ) \
|
|
do { \
|
|
if (1 \
|
|
&& (_regs)->txf_abortctr \
|
|
&& (_regs)->txf_instctr >= (_regs)->txf_abortctr \
|
|
) \
|
|
{ \
|
|
(_regs)->txf_why |= TXF_WHY_RAND_ABORT; \
|
|
ABORT_TRANS( (_regs), -ABORT_RETRY_PGMCHK, \
|
|
(_regs)->txf_random_tac ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#undef CHECK_TXF_CONSTRAINTS
|
|
#define CHECK_TXF_CONSTRAINTS( _ip, _regs ) \
|
|
do { \
|
|
if ((_regs)->txf_tnd) \
|
|
{ \
|
|
TXF_INSTRADDR_CONSTRAINT( (_regs) ); \
|
|
(_regs)->txf_instctr++; \
|
|
TXF_INSTRCOUNT_CONSTRAINT( (_ip), (_regs) ); \
|
|
TXF_RAND_ABORT_CONSTRAINT( (_regs) ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#endif /* !defined( FEATURE_073_TRANSACT_EXEC_FACILITY ) */
|
|
|
|
#undef EXECUTE_INSTRUCTION
|
|
#define EXECUTE_INSTRUCTION( _oct, _ip, _regs ) \
|
|
do { \
|
|
FOOTPRINT( (_ip), (_regs) ); \
|
|
BEG_COUNT_INSTR( (_ip), (_regs) ); \
|
|
(_oct)[ fetch_hw( (_ip) )]( (_ip), (_regs) ); \
|
|
END_COUNT_INSTR( (_ip), (_regs) ); \
|
|
} while (0)
|
|
|
|
#if defined( FEATURE_073_TRANSACT_EXEC_FACILITY )
|
|
|
|
#undef TXF_EXECUTE_INSTRUCTION
|
|
#define TXF_EXECUTE_INSTRUCTION( _oct, _ip, _regs ) \
|
|
do { \
|
|
CHECK_TXF_CONSTRAINTS( (_ip), (_regs) ); \
|
|
FOOTPRINT( (_ip), (_regs) ); \
|
|
BEG_COUNT_INSTR( (_ip), (_regs) ); \
|
|
(_oct)[ fetch_hw( (_ip) )]( (_ip), (_regs) ); \
|
|
END_COUNT_INSTR( (_ip), (_regs) ); \
|
|
} while (0)
|
|
|
|
#undef TXF_UNROLLED_EXECUTE
|
|
#define TXF_UNROLLED_EXECUTE( _oct, _regs ) \
|
|
if ((_regs)->ip >= (_regs)->aie) break; \
|
|
TXF_EXECUTE_INSTRUCTION( (_oct), (_regs)->ip, (_regs) )
|
|
|
|
#endif /* !defined( FEATURE_073_TRANSACT_EXEC_FACILITY ) */
|
|
|
|
#undef UNROLLED_EXECUTE
|
|
#define UNROLLED_EXECUTE( _oct, _regs ) \
|
|
if ((_regs)->ip >= (_regs)->aie) break; \
|
|
EXECUTE_INSTRUCTION( (_oct), (_regs)->ip, (_regs) )
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Branching */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#undef SUCCESSFUL_BRANCH
|
|
#define SUCCESSFUL_BRANCH( _regs, _addr ) \
|
|
\
|
|
ARCH_DEP( SuccessfulBranch )( (_regs), (_addr) )
|
|
|
|
#undef SUCCESSFUL_RELATIVE_BRANCH
|
|
#define SUCCESSFUL_RELATIVE_BRANCH( _regs, _offset ) \
|
|
\
|
|
ARCH_DEP( SuccessfulRelativeBranch )( (_regs), (_offset) )
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* (other) */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
/* Program check if fpc is not valid contents for FPC register */
|
|
#undef FPC_CHECK
|
|
#define FPC_CHECK( _fpc, _regs ) ARCH_DEP( FPC_check )( (_regs), (_fpc) )
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* PER 1 GRA (General Register Alteration) support */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#undef PER_GRA_MASK
|
|
#undef PER_GRA_MASK2
|
|
#undef PER_GRA_MASK4
|
|
#undef PER_GRA_CHECK
|
|
|
|
#if defined( FEATURE_PER1 )
|
|
|
|
#define PER_GRA_MASK( _r1 ) (0x8000 >> (_r1))
|
|
#define PER_GRA_MASK2( _r1, _r2 ) (PER_GRA_MASK( _r1 ) | PER_GRA_MASK( _r2 ))
|
|
#define PER_GRA_MASK4( _r1, _r2, _r3, _r4 ) (PER_GRA_MASK2( _r1, _r2 ) | PER_GRA_MASK2( _r3, _r4 ))
|
|
#define PER_GRA_CHECK( _regs, _mask ) \
|
|
do \
|
|
{ \
|
|
if (1 \
|
|
&& EN_IC_PER_GRA( _regs ) \
|
|
&& (_mask) & ((_regs)->CR(9) & CR9_GRMASK) \
|
|
) \
|
|
ARCH_DEP( per1_gra )( _regs ); \
|
|
} \
|
|
while (0)
|
|
|
|
#else /* !defined( FEATURE_PER1 ) */
|
|
|
|
#define PER_GRA_MASK( _r1 )
|
|
#define PER_GRA_MASK2( _r1, _r2 )
|
|
#define PER_GRA_MASK4( _r1, _r2, _r3, _r4 )
|
|
#define PER_GRA_CHECK( _regs, _mask )
|
|
|
|
#endif /* defined( FEATURE_PER1 ) */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* PER3 Breaking-Event-Address Register (BEAR) */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#undef SET_BEAR_REG
|
|
#undef SET_BEAR_EX_REG
|
|
|
|
#if defined( FEATURE_PER3 )
|
|
|
|
#define SET_BEAR_REG( _regs, _ip ) \
|
|
ARCH_DEP( Set_BEAR_Reg )( &(_regs)->bear, (_regs), (_ip) )
|
|
|
|
#define SET_BEAR_EX_REG( _regs, _ip ) \
|
|
ARCH_DEP( Set_BEAR_Reg )( &(_regs)->bear_ex, (_regs), (_ip) )
|
|
|
|
#else
|
|
|
|
#define SET_BEAR_REG( _regs, _ip )
|
|
#define SET_BEAR_EX_REG( _regs, _ip )
|
|
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* PER3 Event Suppression */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#undef IS_PER_SUPRESS
|
|
|
|
#if defined( FEATURE_PER3 )
|
|
|
|
#define IS_PER_SUPRESS( _regs, _event ) \
|
|
ARCH_DEP( is_per3_event_suppressed )( (_regs), (_event) )
|
|
|
|
#else
|
|
|
|
#define IS_PER_SUPRESS( _regs, _event ) \
|
|
false
|
|
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* PER3 Zero-Address Detection Facility */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#undef PER_ZEROADDR_CHECK
|
|
#undef PER_ZEROADDR_CHECK2
|
|
|
|
#undef PER_ZEROADDR_LCHECK
|
|
#undef PER_ZEROADDR_LCHECK2
|
|
|
|
#undef PER_ZEROADDR_L24CHECK
|
|
#undef PER_ZEROADDR_L24CHECK2
|
|
|
|
#undef PER_ZEROADDR_XCHECK
|
|
#undef PER_ZEROADDR_XCHECK2
|
|
|
|
#if defined( FEATURE_PER_ZERO_ADDRESS_DETECTION_FACILITY )
|
|
|
|
// The CHECK macros are designed for instructions where the operand
|
|
// address is specified in a register but the operand length is not
|
|
// (or is otherwise implied, perhaps by a function code in another
|
|
// operand register for example), and/or for instructions where it
|
|
// is otherwise unpredictable whether operand data will actually be
|
|
// accessed or not. Thus the only thing we can check is whether the
|
|
// register holding the address of the operand is zero or not.
|
|
|
|
#define PER_ZEROADDR_CHECK( _regs, _r1 ) \
|
|
ARCH_DEP( per3_zero_check )((_regs),(_r1))
|
|
|
|
#define PER_ZEROADDR_CHECK2( _regs, _r1, _r2 ) \
|
|
ARCH_DEP( per3_zero_check2 )((_regs),(_r1),(_r2))
|
|
|
|
// The LCHECK macros are designed for RR and RRE and similar format
|
|
// type instructions where a PER Zero-Address event does NOT occur
|
|
// when the operand length (specified in another register) is zero,
|
|
// thus causing that operand's storage to never be accessed. Note
|
|
// that all 32 (or 64) bits of the length register are checked.
|
|
|
|
#define PER_ZEROADDR_LCHECK( _regs, _r1, _l1 ) \
|
|
ARCH_DEP( per3_zero_lcheck )((_regs),(_r1),(_l1))
|
|
|
|
#define PER_ZEROADDR_LCHECK2( _regs, _r1, _l1, _r2, _l2 ) \
|
|
ARCH_DEP( per3_zero_lcheck2 )((_regs),(_r1),(_l1),(_r2),(_l2))
|
|
|
|
// The L24CHECK macros are identical to the LCHECK macros except
|
|
// for the operand length check: instead of checking all 32 or 64
|
|
// bits of the register containing the operand length, we instead
|
|
// check only the low-order 24 bits of the length register via the
|
|
// GR_LA24 macro. They are designed for MVCL and CLCL and other
|
|
// similar type instructions.
|
|
|
|
#define PER_ZEROADDR_L24CHECK( _regs, _r1, _l1 ) \
|
|
ARCH_DEP( per3_zero_l24check )((_regs),(_r1),(_l1))
|
|
|
|
#define PER_ZEROADDR_L24CHECK2( _regs, _r1, _l1, _r2, _l2 ) \
|
|
ARCH_DEP( per3_zero_l24check2 )((_regs),(_r1),(_l1),(_r2),(_l2))
|
|
|
|
// The XCHECK macros are designed for RS/RX/S and similar format
|
|
// type instructions where a PER Zero-Address event does NOT occur
|
|
// unless the specified base or index register number is non-zero.
|
|
// When the base or index register number is specified as zero, it
|
|
// is not used in effective address calculations and thus PER Zero
|
|
// Address Detection does not apply for that register.
|
|
|
|
#define PER_ZEROADDR_XCHECK( _regs, _b1 ) \
|
|
ARCH_DEP( per3_zero_xcheck )((_regs),(_b1))
|
|
|
|
#define PER_ZEROADDR_XCHECK2( _regs, _x2, _b2 ) \
|
|
ARCH_DEP( per3_zero_xcheck2 )((_regs),(_x2),(_b2))
|
|
|
|
#else
|
|
|
|
#define PER_ZEROADDR_CHECK( _regs, _r1 )
|
|
#define PER_ZEROADDR_CHECK2( _regs, _r1, _r2 )
|
|
|
|
#define PER_ZEROADDR_LCHECK( _regs, _r1, _l1 )
|
|
#define PER_ZEROADDR_LCHECK2( _regs, _r1, _l1, _r2, _l2 )
|
|
|
|
#define PER_ZEROADDR_L24CHECK( _regs, _r1, _l1 )
|
|
#define PER_ZEROADDR_L24CHECK2( _regs, _r1, _l1, _r2, _l2 )
|
|
|
|
#define PER_ZEROADDR_XCHECK( _regs, _b1 )
|
|
#define PER_ZEROADDR_XCHECK2( _regs, _x2, _b2 )
|
|
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Set addressing mode (BASSM, BSM) */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#undef SET_ADDRESSING_MODE
|
|
|
|
#if defined( FEATURE_001_ZARCH_INSTALLED_FACILITY )
|
|
|
|
#define SET_ADDRESSING_MODE(_regs, _addr) \
|
|
do { \
|
|
if ((_addr) & 1) { \
|
|
(_regs)->psw.amode64 = regs->psw.amode = 1; \
|
|
(_regs)->psw.AMASK = AMASK64; \
|
|
(_addr) ^= 1; \
|
|
} else if ((_addr) & 0x80000000) { \
|
|
(_regs)->psw.amode64 = 0; \
|
|
(_regs)->psw.amode = 1; \
|
|
(_regs)->psw.AMASK = AMASK31; \
|
|
} else { \
|
|
(_regs)->psw.amode64 = (_regs)->psw.amode = 0; \
|
|
(_regs)->psw.AMASK = AMASK24; \
|
|
} \
|
|
} while (0)
|
|
|
|
#else /* !defined( FEATURE_001_ZARCH_INSTALLED_FACILITY ) */
|
|
|
|
#define SET_ADDRESSING_MODE(_regs, _addr) \
|
|
do { \
|
|
if ((_addr) & 0x80000000) { \
|
|
(_regs)->psw.amode = 1; \
|
|
(_regs)->psw.AMASK = AMASK31; \
|
|
} else { \
|
|
(_regs)->psw.amode = 0; \
|
|
(_regs)->psw.AMASK = AMASK24; \
|
|
} \
|
|
} while (0)
|
|
|
|
#endif /* defined( FEATURE_001_ZARCH_INSTALLED_FACILITY ) */
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Floating-point helper macros */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
// Plain vanilla S/370 mode macros...
|
|
|
|
#undef _370_HFPREG_CHECK
|
|
#undef _370_HFPREG2_CHECK
|
|
#undef _370_HFPODD_CHECK
|
|
#undef _370_HFPODD2_CHECK
|
|
|
|
/* Program check if r1 is not 0, 2, 4, or 6 */
|
|
#define _370_HFPREG_CHECK(_r, _regs) \
|
|
\
|
|
if ((_r) & 9) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION )
|
|
|
|
|
|
/* Program check if r1 and r2 are not 0, 2, 4, or 6 */
|
|
#define _370_HFPREG2_CHECK(_r1, _r2, _regs) \
|
|
\
|
|
if (0 \
|
|
|| ((_r1) & 9) \
|
|
|| ((_r2) & 9) \
|
|
) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION )
|
|
|
|
|
|
/* Program check if r1 is not 0 or 4 */
|
|
#define _370_HFPODD_CHECK(_r, _regs) \
|
|
\
|
|
if ((_r) & 11) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION )
|
|
|
|
|
|
/* Program check if r1 and r2 are not 0 or 4 */
|
|
#define _370_HFPODD2_CHECK(_r1, _r2, _regs) \
|
|
\
|
|
if (0 \
|
|
|| ((_r1) & 11) \
|
|
|| ((_r2) & 11) \
|
|
) \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION )
|
|
|
|
|
|
// Macros for 390 or z/Arch mode, -OR for 370 mode
|
|
// with HERC_370_EXTENSION *maybe* enabled or not...
|
|
|
|
#undef HFPREG_CHECK
|
|
#undef HFPREG2_CHECK
|
|
#undef HFPODD_CHECK
|
|
#undef HFPODD2_CHECK
|
|
|
|
#if !defined( FEATURE_BASIC_FP_EXTENSIONS )
|
|
|
|
// Plain vanilla S/370 mode macros...
|
|
|
|
#define HFPREG_CHECK(_r,_regs) _370_HFPREG_CHECK((_r),(_regs))
|
|
#define HFPREG2_CHECK(_r1,_r2,_regs) _370_HFPREG2_CHECK((_r1),(_r2),(_regs))
|
|
#define HFPODD_CHECK(_r,_regs) _370_HFPODD_CHECK((_r),(_regs))
|
|
#define HFPODD2_CHECK(_r1,_r2,_regs) _370_HFPODD2_CHECK((_r1),(_r2),(_regs))
|
|
|
|
#else /* defined( FEATURE_BASIC_FP_EXTENSIONS ) */
|
|
|
|
#if defined( _FEATURE_SIE )
|
|
|
|
/* Program check if DFP instruction is executed when AFP control is zero */
|
|
#define DFPINST_CHECK(_regs) \
|
|
\
|
|
if (0 \
|
|
|| !((_regs)->CR(0) & CR0_AFP) \
|
|
|| (SIE_MODE((_regs)) && !(HOST(_regs)->CR(0) & CR0_AFP)) \
|
|
) \
|
|
{ \
|
|
(_regs)->dxc = DXC_DFP_INSTRUCTION; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
}
|
|
|
|
/* Program check if BFP instruction is executed when AFP control is zero */
|
|
#define BFPINST_CHECK(_regs) \
|
|
\
|
|
if (0 \
|
|
|| !((_regs)->CR(0) & CR0_AFP) \
|
|
|| (SIE_MODE((_regs)) && !(HOST(_regs)->CR(0) & CR0_AFP)) \
|
|
) \
|
|
{ \
|
|
(_regs)->dxc = DXC_BFP_INSTRUCTION; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
}
|
|
|
|
/* Program check if r1 is not 0, 2, 4, or 6 */
|
|
#define HFPREG_CHECK(_r, _regs) \
|
|
\
|
|
if (0 \
|
|
|| !((_regs)->CR(0) & CR0_AFP) \
|
|
|| (SIE_MODE((_regs)) && !(HOST(_regs)->CR(0) & CR0_AFP)) \
|
|
) \
|
|
{ \
|
|
if (1 \
|
|
&& ARCH_370_IDX == sysblk.arch_mode \
|
|
&& !FACILITY_ENABLED_ARCH( HERC_370_EXTENSION, ARCH_370_IDX ) \
|
|
) \
|
|
{ \
|
|
/* Normal 370 case: HERC_370_EXTENSION not enabled */ \
|
|
_370_HFPREG_CHECK((_r),(_regs)); \
|
|
} \
|
|
else /* 390 or zArch, -OR- 370 with HERC_370_EXTENSION enabled */ \
|
|
{ \
|
|
if ((_r) & 9) \
|
|
{ \
|
|
(_regs)->dxc = DXC_AFP_REGISTER; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
/* Program check if r1 and r2 are not 0, 2, 4, or 6 */
|
|
#define HFPREG2_CHECK(_r1, _r2, _regs) \
|
|
\
|
|
if (0 \
|
|
|| !((_regs)->CR(0) & CR0_AFP) \
|
|
|| (SIE_MODE((_regs)) && !(HOST(_regs)->CR(0) & CR0_AFP)) \
|
|
) \
|
|
{ \
|
|
if (1 \
|
|
&& ARCH_370_IDX == sysblk.arch_mode \
|
|
&& !FACILITY_ENABLED_ARCH( HERC_370_EXTENSION, ARCH_370_IDX ) \
|
|
) \
|
|
{ \
|
|
/* Normal 370 case: HERC_370_EXTENSION not enabled */ \
|
|
_370_HFPREG2_CHECK((_r1),(_r2),(_regs)); \
|
|
} \
|
|
else /* 390 or zArch, -OR- 370 with HERC_370_EXTENSION enabled */ \
|
|
{ \
|
|
if (0 \
|
|
|| ((_r1) & 9) \
|
|
|| ((_r2) & 9) \
|
|
) \
|
|
{ \
|
|
(_regs)->dxc = DXC_AFP_REGISTER; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
/* Program check if r1 is not 0 or 4 */
|
|
#define HFPODD_CHECK(_r, _regs) \
|
|
\
|
|
if (1 \
|
|
&& ARCH_370_IDX == sysblk.arch_mode \
|
|
&& !FACILITY_ENABLED_ARCH( HERC_370_EXTENSION, ARCH_370_IDX ) \
|
|
) \
|
|
{ \
|
|
/* Normal 370 case: HERC_370_EXTENSION not enabled */ \
|
|
_370_HFPODD_CHECK((_r),(_regs)); \
|
|
} \
|
|
else /* 390 or zArch, -OR- 370 with HERC_370_EXTENSION enabled */ \
|
|
{ \
|
|
if ((_r) & 2) \
|
|
{ \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION ); \
|
|
} \
|
|
else if (0 \
|
|
|| !((_regs)->CR(0) & CR0_AFP) \
|
|
|| (SIE_MODE((_regs)) && !(HOST(_regs)->CR(0) & CR0_AFP)) \
|
|
) \
|
|
{ \
|
|
if ((_r) & 9) \
|
|
{ \
|
|
(_regs)->dxc = DXC_AFP_REGISTER; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
/* Program check if r1 and r2 are not 0 or 4 */
|
|
#define HFPODD2_CHECK(_r1, _r2, _regs) \
|
|
\
|
|
if (1 \
|
|
&& ARCH_370_IDX == sysblk.arch_mode \
|
|
&& !FACILITY_ENABLED_ARCH( HERC_370_EXTENSION, ARCH_370_IDX ) \
|
|
) \
|
|
{ \
|
|
/* Normal 370 case: HERC_370_EXTENSION not enabled */ \
|
|
_370_HFPODD2_CHECK((_r1),(_r2),(_regs)); \
|
|
} \
|
|
else /* 390 or zArch, -OR- 370 with HERC_370_EXTENSION enabled */ \
|
|
{ \
|
|
if (0 \
|
|
|| ((_r1) & 2) \
|
|
|| ((_r2) & 2) \
|
|
) \
|
|
{ \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION ); \
|
|
} \
|
|
else if (0 \
|
|
|| !((_regs)->CR(0) & CR0_AFP) \
|
|
|| (SIE_MODE((_regs)) && !(HOST(_regs)->CR(0) & CR0_AFP)) \
|
|
) \
|
|
{ \
|
|
if (0 \
|
|
|| ((_r1) & 9) \
|
|
|| ((_r2) & 9) \
|
|
) \
|
|
{ \
|
|
(_regs)->dxc = DXC_AFP_REGISTER; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#else /* !defined( _FEATURE_SIE ) */
|
|
|
|
/* Program check if DFP instruction is executed when AFP control is zero */
|
|
#define DFPINST_CHECK(_regs) \
|
|
\
|
|
if (!((_regs)->CR(0) & CR0_AFP)) \
|
|
{ \
|
|
(_regs)->dxc = DXC_DFP_INSTRUCTION; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
}
|
|
|
|
/* Program check if BFP instruction is executed when AFP control is zero */
|
|
#define BFPINST_CHECK(_regs) \
|
|
\
|
|
if (!((_regs)->CR(0) & CR0_AFP)) \
|
|
{ \
|
|
(_regs)->dxc = DXC_BFP_INSTRUCTION; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
}
|
|
|
|
/* Program check if r1 is not 0, 2, 4, or 6 */
|
|
#define HFPREG_CHECK(_r,_regs) \
|
|
\
|
|
if (1 \
|
|
&& ARCH_370_IDX == sysblk.arch_mode \
|
|
&& !FACILITY_ENABLED_ARCH( HERC_370_EXTENSION, ARCH_370_IDX ) \
|
|
) \
|
|
{ \
|
|
/* Normal 370 case: HERC_370_EXTENSION not enabled */ \
|
|
_370_HFPREG_CHECK((_r),(_regs)); \
|
|
} \
|
|
else /* 390 or zArch, -OR- 370 with HERC_370_EXTENSION enabled */ \
|
|
{ \
|
|
if (!((_regs)->CR(0) & CR0_AFP)) \
|
|
{ \
|
|
if ((_r) & 9) \
|
|
{ \
|
|
(_regs)->dxc = DXC_AFP_REGISTER; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
/* Program check if r1 and r2 are not 0, 2, 4, or 6 */
|
|
#define HFPREG2_CHECK(_r1,_r2,_regs) \
|
|
\
|
|
if (1 \
|
|
&& ARCH_370_IDX == sysblk.arch_mode \
|
|
&& !FACILITY_ENABLED_ARCH( HERC_370_EXTENSION, ARCH_370_IDX ) \
|
|
) \
|
|
{ \
|
|
/* Normal 370 case: HERC_370_EXTENSION not enabled */ \
|
|
_370_HFPREG2_CHECK((_r1),(_r2),(_regs)); \
|
|
} \
|
|
else /* 390 or zArch, -OR- 370 with HERC_370_EXTENSION enabled */ \
|
|
{ \
|
|
if (!((_regs)->CR(0) & CR0_AFP) ) \
|
|
{ \
|
|
if (0 \
|
|
|| ((_r1) & 9) \
|
|
|| ((_r2) & 9) \
|
|
) \
|
|
{ \
|
|
(_regs)->dxc = DXC_AFP_REGISTER; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
/* Program check if r1 is not 0 or 4 */
|
|
#define HFPODD_CHECK(_r,_regs) \
|
|
\
|
|
if (1 \
|
|
&& ARCH_370_IDX == sysblk.arch_mode \
|
|
&& !FACILITY_ENABLED_ARCH( HERC_370_EXTENSION, ARCH_370_IDX ) \
|
|
) \
|
|
{ \
|
|
/* Normal 370 case: HERC_370_EXTENSION not enabled */ \
|
|
_370_HFPODD_CHECK((_r),(_regs)); \
|
|
} \
|
|
else /* 390 or zArch, -OR- 370 with HERC_370_EXTENSION enabled */ \
|
|
{ \
|
|
if ((_r) & 2) \
|
|
{ \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION ); \
|
|
} \
|
|
else if (!((_regs)->CR(0) & CR0_AFP) ) \
|
|
{ \
|
|
if ((_r) & 9) \
|
|
{ \
|
|
(_regs)->dxc = DXC_AFP_REGISTER; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
/* Program check if r1 and r2 are not 0 or 4 */
|
|
#define HFPODD2_CHECK(_r1,_r2,_regs) \
|
|
\
|
|
if (1 \
|
|
&& ARCH_370_IDX == sysblk.arch_mode \
|
|
&& !FACILITY_ENABLED_ARCH( HERC_370_EXTENSION, ARCH_370_IDX ) \
|
|
) \
|
|
{ \
|
|
/* Normal 370 case: HERC_370_EXTENSION not enabled */ \
|
|
_370_HFPODD2_CHECK((_r1),(_r2),(_regs)); \
|
|
} \
|
|
else /* 390 or zArch, -OR- 370 with HERC_370_EXTENSION enabled */ \
|
|
{ \
|
|
if (0 \
|
|
|| ((_r1) & 2) \
|
|
|| ((_r2) & 2) \
|
|
) \
|
|
{ \
|
|
(_regs)->program_interrupt( (_regs), PGM_SPECIFICATION_EXCEPTION ); \
|
|
} \
|
|
else if (!((_regs)->CR(0) & CR0_AFP) ) \
|
|
{ \
|
|
if (0 \
|
|
|| ((_r1) & 9) \
|
|
|| ((_r2) & 9) \
|
|
) \
|
|
{ \
|
|
(_regs)->dxc = DXC_AFP_REGISTER; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION ); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#endif /* !defined( _FEATURE_SIE ) */
|
|
|
|
#endif /* !defined( FEATURE_BASIC_FP_EXTENSIONS ) */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* (end floating-point helper macros) */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define TLBIX(_addr) (((VADR_L)(_addr) >> TLB_PAGESHIFT) & TLB_MASK)
|
|
|
|
#define MAINADDR(_main, _addr) \
|
|
(BYTE*)((uintptr_t)(_main) ^ (uintptr_t)(_addr))
|
|
|
|
#define NEW_MAINADDR(_regs, _addr, _aaddr) \
|
|
(BYTE*)((uintptr_t)((_regs)->mainstor \
|
|
+ (uintptr_t)(_aaddr)) \
|
|
^ (uintptr_t)((_addr) & TLB_PAGEMASK))
|
|
|
|
#define MAIN_TO_ABS(_main) ((U64)((BYTE*)(_main) - sysblk.mainstor))
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* zVector Facility */
|
|
/*-------------------------------------------------------------------*/
|
|
#if defined( _FEATURE_129_ZVECTOR_FACILITY )
|
|
|
|
/* Program check if vector instructions are executed when TXF */
|
|
/* constraint mode, or if the vector enablement control (bit */
|
|
/* 46) and the AFP control (bit 45) in control register zero */
|
|
/* are not set to one. */
|
|
|
|
#if defined( _FEATURE_SIE )
|
|
|
|
#define ZVECTOR_CHECK(_regs) \
|
|
TXF_INSTR_CHECK(_regs); \
|
|
if (0 \
|
|
|| !((_regs)->CR(0) & CR0_VOP) \
|
|
|| !((_regs)->CR(0) & CR0_AFP) \
|
|
|| (SIE_MODE((_regs)) && (0 \
|
|
|| !(HOST(_regs)->CR(0) & CR0_VOP) \
|
|
|| !(HOST(_regs)->CR(0) & CR0_AFP))) \
|
|
) \
|
|
{ \
|
|
(_regs)->dxc = DXC_VECTOR_INSTRUCTION; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION); \
|
|
}
|
|
|
|
#else /* !defined( _FEATURE_SIE ) */
|
|
|
|
#define ZVECTOR_CHECK(_regs) \
|
|
TXF_INSTR_CHECK(_regs); \
|
|
if (0 \
|
|
|| !((_regs)->CR(0) & CR0_VOP) \
|
|
|| !((_regs)->CR(0) & CR0_AFP) \
|
|
) \
|
|
{ \
|
|
(_regs)->dxc = DXC_VECTOR_INSTRUCTION; \
|
|
(_regs)->program_interrupt( (_regs), PGM_DATA_EXCEPTION); \
|
|
}
|
|
|
|
#endif /* !defined( _FEATURE_SIE ) */
|
|
|
|
/* Debug end of vector instruction execution */
|
|
|
|
#define ZVECTOR_END(_regs) /* (do nothing) */
|
|
|
|
#endif /*defined( _FEATURE_129_ZVECTOR_FACILITY )*/
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Perform invalidation after storage key update... */
|
|
/*-------------------------------------------------------------------*/
|
|
/* */
|
|
/* If the REF or CHANGE bit is turned off for an absolute address, */
|
|
/* then we need to invalidate any cached entries for that address */
|
|
/* on *ALL* CPUs. */
|
|
/* */
|
|
/* FIXME: Synchronization, esp. for the CHANGE bit, should be */
|
|
/* tighter than what is provided here. */
|
|
/* */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#define STORKEY_INVALIDATE_LOCKED( _regs, _n ) \
|
|
\
|
|
do \
|
|
{ \
|
|
BYTE* abs = (_regs)->mainstor + ((_n) & PAGEFRAME_PAGEMASK); \
|
|
\
|
|
/* Do it for the current CPU first */ \
|
|
ARCH_DEP( invalidate_tlbe )( (_regs), abs ); \
|
|
\
|
|
if (sysblk.cpus > 1) \
|
|
{ \
|
|
int cpu; /* CPU being examined */ \
|
|
REGS* cregs; /* register context for CPU being examined */ \
|
|
\
|
|
/* Do invalidate for all of the other online CPUs too */ \
|
|
for (cpu=0; cpu < sysblk.hicpu; cpu++) \
|
|
{ \
|
|
/* Skip our own CPU and CPUs which aren't online */ \
|
|
if (IS_CPU_ONLINE( cpu ) && cpu != (_regs)->cpuad) \
|
|
{ \
|
|
cregs = sysblk.regs[cpu]; \
|
|
\
|
|
/* Is this CPU waiting for an interrupt? */ \
|
|
if (sysblk.waiting_mask & CPU_BIT( cpu )) \
|
|
{ \
|
|
/* Yes, then we can do the invalidate right now... */ \
|
|
switch (cregs->arch_mode) \
|
|
{ \
|
|
case ARCH_370_IDX: \
|
|
{ \
|
|
abs = cregs->mainstor + ((_n) & PAGEFRAME_370_PAGEMASK); \
|
|
s370_invalidate_tlbe( cregs, abs ); \
|
|
break; \
|
|
} \
|
|
case ARCH_390_IDX: \
|
|
{ \
|
|
abs = cregs->mainstor + ((_n) & PAGEFRAME_390_PAGEMASK); \
|
|
s390_invalidate_tlbe( cregs, abs ); \
|
|
break; \
|
|
} \
|
|
case ARCH_900_IDX: \
|
|
{ \
|
|
abs = cregs->mainstor + ((_n) & PAGEFRAME_900_PAGEMASK); \
|
|
z900_invalidate_tlbe( cregs, abs ); \
|
|
break; \
|
|
} \
|
|
default: \
|
|
{ \
|
|
CRASH(); \
|
|
} \
|
|
} \
|
|
} \
|
|
else /* Otherwise we need to schedule it ... */ \
|
|
{ \
|
|
ON_IC_INTERRUPT( cregs ); \
|
|
\
|
|
if (!cregs->invalidate) \
|
|
{ \
|
|
cregs->invalidate = 1; \
|
|
cregs->invalidate_main = abs; \
|
|
} \
|
|
else \
|
|
{ \
|
|
cregs->invalidate_main = NULL; \
|
|
} \
|
|
} \
|
|
} \
|
|
} \
|
|
} \
|
|
} \
|
|
while (0)
|
|
|
|
#define STORKEY_INVALIDATE( _regs, _n ) \
|
|
do \
|
|
{ \
|
|
OBTAIN_INTLOCK( (_regs) ); \
|
|
{ \
|
|
STORKEY_INVALIDATE_LOCKED( (_regs), (_n) ); \
|
|
} \
|
|
RELEASE_INTLOCK( (_regs) ); \
|
|
} \
|
|
while (0)
|
|
|
|
#if defined( INLINE_STORE_FETCH_ADDR_CHECK )
|
|
#define FETCH_MAIN_ABSOLUTE(_addr, _regs, _len) \
|
|
ARCH_DEP( fetch_main_absolute )((_addr), (_regs), (_len))
|
|
#else
|
|
#define FETCH_MAIN_ABSOLUTE(_addr, _regs, _len) \
|
|
ARCH_DEP( fetch_main_absolute )((_addr), (_regs))
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Transactional-Execution Facility (TXF) support macros */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#undef TXFC_INSTR_CHECK /* 'TXFC' == Constrained */
|
|
#undef TXFC_INSTR_CHECK_IP /* 'TXFC' == Constrained */
|
|
#undef TXFC_BRANCH_CHECK_IP /* 'TXFC' == Constrained */
|
|
#undef TXFC_RELATIVE_BRANCH_CHECK_IP /* 'TXFC' == Constrained */
|
|
|
|
#undef TXF_INSTR_CHECK
|
|
#undef TXF_FLOAT_INSTR_CHECK
|
|
#undef TXF_ACCESS_INSTR_CHECK
|
|
#undef TXF_NONRELATIVE_BRANCH_CHECK_IP
|
|
#undef TXF_BRANCH_SET_MODE_CHECK_IP
|
|
#undef TXF_SET_ADDRESSING_MODE_CHECK
|
|
#undef TXF_MISC_INSTR_CHECK
|
|
#undef TXF_EXECUTE_INSTR_CHECK
|
|
#undef TXF_ALLOCMAP
|
|
#undef TXF_FREEMAP
|
|
#undef TXF_MADDRL
|
|
|
|
#if !defined( FEATURE_073_TRANSACT_EXEC_FACILITY )
|
|
|
|
#define TXFC_INSTR_CHECK( _regs )
|
|
#define TXFC_INSTR_CHECK_IP( _regs )
|
|
#define TXFC_BRANCH_CHECK_IP( _regs, _m3, _i4 )
|
|
#define TXFC_RELATIVE_BRANCH_CHECK_IP( _regs )
|
|
|
|
#define TXF_INSTR_CHECK( _regs )
|
|
#define TXF_FLOAT_INSTR_CHECK( _regs )
|
|
#define TXF_ACCESS_INSTR_CHECK( _regs )
|
|
#define TXF_MISC_INSTR_CHECK( _regs )
|
|
#define TXF_NONRELATIVE_BRANCH_CHECK_IP( _regs, _r )
|
|
#define TXF_BRANCH_SET_MODE_CHECK_IP( _regs, _r2 )
|
|
#define TXF_SET_ADDRESSING_MODE_CHECK( _regs )
|
|
#define TXF_EXECUTE_INSTR_CHECK( _regs )
|
|
#define TXF_ALLOCMAP( _regs )
|
|
#define TXF_FREEMAP( _regs )
|
|
|
|
#define TXF_MADDRL( _vaddr, _len, _arn, _regs, _acctype, _maddr ) \
|
|
/* Return the very same address as what was passed */ (_maddr)
|
|
|
|
#else /* defined( FEATURE_073_TRANSACT_EXEC_FACILITY ) */
|
|
|
|
#define TXFC_INSTR_CHECK( _regs ) \
|
|
/* Restricted instruction in CONSTRAINED transaction mode */ \
|
|
do { \
|
|
if ((_regs)->txf_contran) \
|
|
{ \
|
|
(_regs)->txf_why |= TXF_WHY_CONTRAN_INSTR; \
|
|
ABORT_TRANS( (_regs), ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXFC_INSTR_CHECK_IP( _regs ) \
|
|
/* Restricted instruction in CONSTRAINED transaction mode */ \
|
|
do { \
|
|
if ((_regs)->txf_contran) \
|
|
{ \
|
|
/* Since the instruction hasn't been decoded yet, regs->ip is still \
|
|
pointing to the instruction so we use NEGATIVE "ABORT_RETRY_PGMCHK". \
|
|
See the comments in the "abort_transaction" function in transact.c \
|
|
*/ \
|
|
(_regs)->txf_why |= TXF_WHY_CONTRAN_INSTR; \
|
|
ABORT_TRANS( (_regs), -ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXFC_BRANCH_CHECK_IP( _regs, _m3, _i4 ) \
|
|
/* Branches restricted in CONSTRAINED mode if mask zero or offset negative */ \
|
|
do { \
|
|
if ((_regs)->txf_contran && \
|
|
(0 \
|
|
|| (_m3) == 0x00 /* zero mask (nop) not allowed */ \
|
|
|| (_i4) < 0 /* backward branches not allowed */ \
|
|
)) \
|
|
{ \
|
|
/* Since the instruction hasn't been decoded yet, regs->ip is still \
|
|
pointing to the instruction so we use NEGATIVE "ABORT_RETRY_PGMCHK". \
|
|
See the comments in the "abort_transaction" function in transact.c \
|
|
*/ \
|
|
(_regs)->txf_why |= TXF_WHY_CONTRAN_BRANCH; \
|
|
ABORT_TRANS( (_regs), -ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXFC_RELATIVE_BRANCH_CHECK_IP( _regs ) \
|
|
/* Relative branches restricted in CONSTRAINED mode */ \
|
|
/* if the mask is zero or the offset is negative */ \
|
|
do { \
|
|
if ((_regs)->txf_contran && \
|
|
(0 \
|
|
|| (inst[1] & 0xf0) == 0x00 \
|
|
|| (inst[2] & 0x80) \
|
|
)) \
|
|
{ \
|
|
/* Since the instruction hasn't been decoded yet, regs->ip is still \
|
|
pointing to the instruction so we use NEGATIVE "ABORT_RETRY_PGMCHK". \
|
|
See the comments in the "abort_transaction" function in transact.c \
|
|
*/ \
|
|
(_regs)->txf_why |= TXF_WHY_CONTRAN_RELATIVE_BRANCH; \
|
|
ABORT_TRANS( (_regs), -ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXF_INSTR_CHECK( _regs ) \
|
|
/* Restricted instruction in any transaction mode */ \
|
|
do { \
|
|
if ((_regs)->txf_tnd) \
|
|
{ \
|
|
(_regs)->txf_why |= TXF_WHY_TRAN_INSTR; \
|
|
ABORT_TRANS( (_regs), ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXF_FLOAT_INSTR_CHECK( _regs ) \
|
|
/* Restricted instruction if CONSTRAINED mode or float bit zero */ \
|
|
do { \
|
|
if (1 \
|
|
&& (_regs)->txf_tnd \
|
|
&& (0 \
|
|
|| (_regs)->txf_contran \
|
|
|| !((_regs)->txf_ctlflag & TXF_CTL_FLOAT) \
|
|
) \
|
|
) \
|
|
{ \
|
|
(_regs)->txf_why |= TXF_WHY_TRAN_FLOAT_INSTR; \
|
|
ABORT_TRANS( (_regs), ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXF_ACCESS_INSTR_CHECK( _regs ) \
|
|
/* Restricted instruction if access control bit zero */ \
|
|
do { \
|
|
if (1 \
|
|
&& (_regs)->txf_tnd \
|
|
&& !((_regs)->txf_ctlflag & TXF_CTL_AR) \
|
|
) \
|
|
{ \
|
|
(_regs)->txf_why |= TXF_WHY_TRAN_ACCESS_INSTR; \
|
|
ABORT_TRANS( (_regs), ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXF_NONRELATIVE_BRANCH_CHECK_IP( _regs, _r ) \
|
|
/* BALR/BASR/BASSM are restricted when the branch */ \
|
|
/* register is non-zero and BRANCH tracing is enabled */ \
|
|
do { \
|
|
if (1 \
|
|
&& (_regs)->txf_tnd \
|
|
&& ((_r) != 0 && ((_regs)->CR(12) & CR12_BRTRACE)) \
|
|
) \
|
|
{ \
|
|
/* Since the instruction hasn't been decoded yet, regs->ip is still \
|
|
pointing to the instruction so we use NEGATIVE "ABORT_RETRY_PGMCHK". \
|
|
See the comments in the "abort_transaction" function in transact.c \
|
|
*/ \
|
|
(_regs)->txf_why |= TXF_WHY_TRAN_NONRELATIVE_BRANCH; \
|
|
ABORT_TRANS( (_regs), -ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXF_BRANCH_SET_MODE_CHECK_IP( _regs, _r2 ) \
|
|
/* BASSM/BSM are restricted if the r2 field */ \
|
|
/* is non-zero and MODE tracing is enabled. */ \
|
|
do { \
|
|
if (1 \
|
|
&& (_regs)->txf_tnd \
|
|
&& ((_r2) != 0 && ((_regs)->CR(12) & CR12_MTRACE)) \
|
|
) \
|
|
{ \
|
|
/* Since the instruction hasn't been decoded yet, regs->ip is still \
|
|
pointing to the instruction so we use NEGATIVE "ABORT_RETRY_PGMCHK". \
|
|
See the comments in the "abort_transaction" function in transact.c \
|
|
*/ \
|
|
(_regs)->txf_why |= TXF_WHY_TRAN_BRANCH_SET_MODE; \
|
|
ABORT_TRANS( (_regs), -ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXF_SET_ADDRESSING_MODE_CHECK( _regs ) \
|
|
/* SAM24/31/64 is restricted if mode tracing is enabled. */ \
|
|
do { \
|
|
if (1 \
|
|
&& (_regs)->txf_tnd \
|
|
&& ((_regs)->CR(12) & CR12_MTRACE) \
|
|
) \
|
|
{ \
|
|
(_regs)->txf_why |= TXF_WHY_TRAN_SET_ADDRESSING_MODE; \
|
|
ABORT_TRANS( (_regs), ABORT_RETRY_PGMCHK, TAC_INSTR ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXF_MISC_INSTR_CHECK( _regs ) \
|
|
/* Restricted instruction in any transaction mode */ \
|
|
do { \
|
|
if ((_regs)->txf_tnd) \
|
|
{ \
|
|
(_regs)->txf_why |= TXF_WHY_TRAN_MISC_INSTR; \
|
|
ABORT_TRANS( (_regs), ABORT_RETRY_PGMCHK, TAC_MISC ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXF_EXECUTE_INSTR_CHECK( _regs ) \
|
|
/* Most all TXF instructions cannot be executed */ \
|
|
do { \
|
|
if ((_regs)->execflag) \
|
|
{ \
|
|
ARCH_DEP( program_interrupt )( (_regs), PGM_EXECUTE_EXCEPTION ); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define TXF_MADDRL( _vaddr, _len, _arn, _regs, _acctype, _maddr ) \
|
|
txf_maddr_l( (_vaddr), (_len), (_arn), (_regs), (_acctype), (_maddr) )
|
|
|
|
#define TXF_ALLOCMAP( _regs ) alloc_txfmap( _regs )
|
|
#define TXF_FREEMAP( _regs ) free_txfmap( _regs )
|
|
|
|
#endif /* defined( FEATURE_073_TRANSACT_EXEC_FACILITY ) */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Instruction decoders */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#include "instfmts.h" // (moved into separate #include header)
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* SIE address translation macros */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#undef SIE_LOGICAL_TO_ABS
|
|
#undef SIE_TRANSLATE_ADDR
|
|
#undef SIE_TRANSLATE
|
|
|
|
#if defined( _FEATURE_SIE )
|
|
|
|
//-------------------------------------------------------------------
|
|
// SIE_LOGICAL_TO_ABS: SIE host virt --> SIE host abs
|
|
// SIE_TRANSLATE_ADDR: SIE host virt --> SIE host real; rc
|
|
//-------------------------------------------------------------------
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// z/Arch running under z/VM, or ESA/390 running under VM/ESA
|
|
// --------------------------------------------------------------------------------
|
|
|
|
#if __GEN_ARCH == 900 || (__GEN_ARCH == 390 && !defined( _FEATURE_ZSIE ))
|
|
|
|
#define SIE_LOGICAL_TO_ABS( _addr, _arn, _regs, _acctype, _akey ) \
|
|
( \
|
|
ARCH_DEP( logical_to_main_l )( (_addr), (_arn), (_regs), (_acctype), (_akey), 1 ), \
|
|
(_regs)->dat.aaddr /* THIS IS THE ACTUAL VALUE THE MACRO RETURNS! */ \
|
|
)
|
|
|
|
#define SIE_TRANSLATE_ADDR( _addr, _arn, _regs, _acctype ) \
|
|
\
|
|
ARCH_DEP( translate_addr )( (_addr), (_arn), (_regs), (_acctype) )
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// S/370 running under VM/ESA
|
|
// --------------------------------------------------------------------------------
|
|
|
|
#elif __GEN_ARCH == 370 && defined( _FEATURE_SIE )
|
|
|
|
#define SIE_LOGICAL_TO_ABS( _addr, _arn, _regs, _acctype, _akey ) \
|
|
( \
|
|
s390_logical_to_main_l( (_addr), (_arn), (_regs), (_acctype), (_akey), 1 ), \
|
|
(_regs)->dat.aaddr /* THIS IS THE ACTUAL VALUE THE MACRO RETURNS! */ \
|
|
)
|
|
|
|
#define SIE_TRANSLATE_ADDR( _addr, _arn, _regs, _acctype ) \
|
|
\
|
|
s390_translate_addr( (_addr), (_arn), (_regs), (_acctype) )
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// ESA/390 running under z/VM
|
|
// --------------------------------------------------------------------------------
|
|
|
|
#else /* __GEN_ARCH == 390 && defined( _FEATURE_ZSIE ) */
|
|
|
|
#define SIE_LOGICAL_TO_ABS( _addr, _arn, _regs, _acctype, _akey ) \
|
|
( \
|
|
((ARCH_390_IDX == (_regs)->arch_mode) \
|
|
? s390_logical_to_main_l( (_addr), (_arn), (_regs), (_acctype), (_akey), 1 ) \
|
|
: z900_logical_to_main_l( (_addr), (_arn), (_regs), (_acctype), (_akey), 1 )), \
|
|
(_regs)->dat.aaddr /* THIS IS THE ACTUAL VALUE THE MACRO RETURNS! */ \
|
|
)
|
|
|
|
#define SIE_TRANSLATE_ADDR( _addr, _arn, _regs, _acctype ) \
|
|
( \
|
|
(ARCH_390_IDX == (_regs)->arch_mode) \
|
|
? s390_translate_addr( (_addr), (_arn), (_regs), (_acctype) ) \
|
|
: z900_translate_addr( (_addr), (_arn), (_regs), (_acctype) ) \
|
|
)
|
|
|
|
#endif // __GEN_ARCH == ...
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// SIE_TRANSLATE: SIE guest abs --> SIE host abs (or nop if not in SIE mode)
|
|
// --------------------------------------------------------------------------------
|
|
|
|
#define SIE_TRANSLATE( _addr, _acctype, _regs ) \
|
|
\
|
|
do { \
|
|
if (SIE_MODE( (_regs) ) && !(_regs)->sie_pref) /* SIE mode? */ \
|
|
*(_addr) = SIE_LOGICAL_TO_ABS( /* host virt --> host abs */ \
|
|
(_regs)->sie_mso + *(_addr), /* guest abs is host virt */ \
|
|
USE_PRIMARY_SPACE, /* host primary virtual */ \
|
|
HOST(_regs), /* host register context */ \
|
|
(_acctype), 0 ); /* access type and skey */ \
|
|
} while (0)
|
|
|
|
#else // !defined( _FEATURE_SIE )
|
|
|
|
#define SIE_TRANSLATE_ADDR( _addr, _arn, _regs, _acctype )
|
|
#define SIE_LOGICAL_TO_ABS( _addr, _arn, _regs, _acctype, _akey )
|
|
#define SIE_TRANSLATE( _addr, _acctype, _regs )
|
|
|
|
#endif // defined( _FEATURE_SIE )
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* other SIE helper macros */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#undef SIE_INTERCEPT
|
|
#undef SIE_XC_INTERCEPT
|
|
#undef SIE_SET_VI
|
|
|
|
#if defined( _FEATURE_SIE )
|
|
|
|
/*---------------------------------------------*/
|
|
/* SIE intercept if SIE mode */
|
|
/*---------------------------------------------*/
|
|
#define SIE_INTERCEPT( _regs ) \
|
|
\
|
|
do { \
|
|
if (SIE_MODE( _regs )) \
|
|
longjmp( (_regs)->progjmp, SIE_INTERCEPT_INST ); \
|
|
} \
|
|
while (0)
|
|
|
|
/*---------------------------------------------*/
|
|
/* SIE intercept if XC mode guest */
|
|
/*---------------------------------------------*/
|
|
#if defined( FEATURE_MULTIPLE_CONTROLLED_DATA_SPACE )
|
|
#define SIE_XC_INTERCEPT( _regs ) \
|
|
\
|
|
do { \
|
|
if (SIE_MODE( _regs ) && SIE_STATE_BIT_ON( (_regs), MX, XC )) \
|
|
longjmp( (_regs)->progjmp, SIE_INTERCEPT_INST ); \
|
|
} \
|
|
while (0)
|
|
#else
|
|
#define SIE_XC_INTERCEPT( _regs )
|
|
#endif
|
|
|
|
/*---------------------------------------------*/
|
|
/* Set SIE Validity Intercept fields */
|
|
/*---------------------------------------------*/
|
|
#define SIE_SET_VI( _who, _when, _why, _regs ) \
|
|
do { \
|
|
(_regs)->siebk->vi_who = (_who); \
|
|
(_regs)->siebk->vi_when = (_when); \
|
|
STORE_HW( (_regs)->siebk->vi_why, (_why) ); \
|
|
memset( (_regs)->siebk->vi_zero, 0, 6 ); \
|
|
} \
|
|
while (0)
|
|
|
|
#else // !defined( _FEATURE_SIE )
|
|
|
|
#define SIE_INTERCEPT( _regs )
|
|
#define SIE_XC_INTERCEPT( _regs )
|
|
#define SIE_SET_VI( _who, _when, _why, _regs )
|
|
|
|
#endif // defined( _FEATURE_SIE )
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Instruction serialization */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#if defined( OPTION_HARDWARE_SYNC_ALL )
|
|
#define PERFORM_SERIALIZATION( _regs ) HARDWARE_SYNC()
|
|
#define PERFORM_CHKPT_SYNC( _regs ) do{}while(0)
|
|
#else
|
|
#define PERFORM_SERIALIZATION( _regs ) do{}while(0)
|
|
#define PERFORM_CHKPT_SYNC( _regs ) do{}while(0)
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* External function declarations */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
/* Functions in module channel.c */
|
|
int ARCH_DEP( startio ) (REGS *regs, DEVBLK *dev, ORB *orb);
|
|
|
|
void *s370_execute_ccw_chain (void *dev);
|
|
void *s390_execute_ccw_chain (void *dev);
|
|
void *z900_execute_ccw_chain (void *dev);
|
|
|
|
int stchan_id (REGS *regs, U16 chan);
|
|
int testch (REGS *regs, U16 chan);
|
|
int testio (REGS *regs, DEVBLK *dev, BYTE ibyte);
|
|
int test_subchan (REGS *regs, DEVBLK *dev, IRB *irb);
|
|
int cancel_subchan (REGS *regs, DEVBLK *dev);
|
|
void clear_subchan (REGS *regs, DEVBLK *dev);
|
|
int halt_subchan (REGS *regs, DEVBLK *dev);
|
|
int haltio (REGS *regs, DEVBLK *dev, BYTE ibyte);
|
|
int resume_subchan (REGS *regs, DEVBLK *dev);
|
|
|
|
int ARCH_DEP( present_io_interrupt ) (REGS *regs, U32 *ioid, U32 *ioparm, U32 *iointid, BYTE *csw, DEVBLK** pdev );
|
|
int ARCH_DEP( present_zone_io_interrupt ) (U32 *ioid, U32 *ioparm, U32 *iointid, BYTE zone);
|
|
|
|
void io_reset (void);
|
|
int chp_reset(BYTE chpid, int solicited);
|
|
void channelset_reset(REGS *regs);
|
|
|
|
|
|
/* Functions in module cpu.c */
|
|
/* define all arch_load|store_psw */
|
|
/* regardless of current architecture (if any)
|
|
*/
|
|
#if defined( _370 )
|
|
void s370_store_psw (REGS *regs, BYTE *addr);
|
|
int s370_load_psw (REGS *regs, BYTE *addr);
|
|
void s370_process_trace( REGS* regs, BYTE* dest );
|
|
#endif
|
|
|
|
#if defined( _390 )
|
|
int s390_load_psw (REGS *regs, BYTE *addr);
|
|
void s390_store_psw (REGS *regs, BYTE *addr);
|
|
void s390_process_trace( REGS* regs, BYTE* dest );
|
|
#endif
|
|
|
|
#if defined( _900 )
|
|
int z900_load_psw (REGS *regs, BYTE *addr);
|
|
void z900_store_psw (REGS *regs, BYTE *addr);
|
|
void z900_process_trace( REGS* regs, BYTE* dest );
|
|
#endif
|
|
|
|
int cpu_init (int cpu, REGS *regs, REGS *hostregs);
|
|
void ARCH_DEP( perform_io_interrupt ) (REGS *regs);
|
|
void ARCH_DEP( checkstop_all_cpus )( REGS* regs );
|
|
U64 make_psw64( REGS* regs, int arch /*370/390/900*/, bool bc );
|
|
|
|
#if defined( FEATURE_PER3 )
|
|
CPU_DLL_IMPORT void ARCH_DEP( Set_BEAR_Reg )( U64* bear, REGS* regs, BYTE* ip );
|
|
#endif
|
|
|
|
CPU_DLL_IMPORT void ARCH_DEP( SuccessfulBranch )( REGS* regs, VADR vaddr );
|
|
CPU_DLL_IMPORT void ARCH_DEP( SuccessfulRelativeBranch )( REGS* regs, S64 offset );
|
|
CPU_DLL_IMPORT int ARCH_DEP( fix_program_interrupt_PSW )( REGS* regs );
|
|
CPU_DLL_IMPORT void ARCH_DEP( trace_program_interrupt )( REGS* regs, int pcode, int ilc );
|
|
|
|
void *cpu_thread (void *cpu);
|
|
CPU_DLL_IMPORT void copy_psw (REGS *regs, BYTE *addr);
|
|
int display_psw( REGS* regs, char* buf, int buflen );
|
|
char* str_psw( REGS* regs, char* buf, int buflen );
|
|
char* str_arch_psw( int arch_mode, REGS* regs, char* buf, int buflen );
|
|
// (helper macros for use with char arrays. DON'T USE IF BUF IS CHAR POINTER!)
|
|
#define DISPLAY_PSW( _regs, _buf ) display_psw ( (_regs), (_buf), (int) sizeof( _buf ))
|
|
#define STR_PSW( _regs, _buf ) str_psw ( (_regs), (_buf), (int) sizeof( _buf ))
|
|
#define STR_ARCH_PSW( _arch, _regs, _buf ) str_arch_psw ( (_arch), (_regs), (_buf), (int) sizeof( _buf ))
|
|
|
|
#define DO_AUTOMATIC_TRACING() if (sysblk.auto_trace_amt) do_automatic_tracing();
|
|
void do_automatic_tracing();
|
|
|
|
|
|
/* Functions in module vm.c */
|
|
int ARCH_DEP( diag_devtype ) ( int r1, int r2, REGS *regs);
|
|
int ARCH_DEP( syncblk_io ) ( int r1, int r2, REGS *regs);
|
|
int ARCH_DEP( syncgen_io ) ( int r1, int r2, REGS *regs);
|
|
void ARCH_DEP( extid_call ) ( int r1, int r2, REGS *regs);
|
|
int ARCH_DEP( cpcmd_call ) ( int r1, int r2, REGS *regs);
|
|
int ARCH_DEP( diag_ppagerel ) ( int r1, int r2, REGS *regs);
|
|
void ARCH_DEP( vm_info ) ( int r1, int r2, REGS *regs);
|
|
int ARCH_DEP( device_info ) ( int r1, int r2, REGS *regs);
|
|
void ARCH_DEP( access_reipl_data ) ( int r1, int r2, REGS *regs);
|
|
void ARCH_DEP( pseudo_timer ) (U32 code, int r1, int r2, REGS *regs);
|
|
|
|
|
|
/* Functions in module vmd250.c */
|
|
int ARCH_DEP( vm_blockio ) (int r1, int r2, REGS *regs);
|
|
|
|
|
|
/* Functions in module control.c */
|
|
void ARCH_DEP( load_real_address_proc ) (REGS *regs,
|
|
int r1, int b2, VADR effective_addr2);
|
|
|
|
|
|
/* Functions in module decimal.c */
|
|
void packed_to_binary (BYTE *dec, int len, U64 *result,
|
|
int *ovf, int *dxf);
|
|
void binary_to_packed (S64 bin, BYTE *result);
|
|
|
|
|
|
/* Functions in module diagnose.c */
|
|
void ARCH_DEP( diagnose_call )( REGS* regs, int r1, int r3, int b2, VADR effective_addr2 );
|
|
|
|
|
|
/* Functions in module diagmssf.c */
|
|
void ARCH_DEP( scpend_call ) (void);
|
|
int ARCH_DEP( mssf_call ) (int r1, int r2, REGS *regs);
|
|
void ARCH_DEP( diag204_call ) (int r1, int r2, REGS *regs);
|
|
void ARCH_DEP( diag224_call ) (int r1, int r2, REGS *regs);
|
|
|
|
|
|
/* Functions in module external.c */
|
|
void ARCH_DEP( perform_external_interrupt ) (REGS *regs);
|
|
void ARCH_DEP( store_status ) (REGS *ssreg, RADR aaddr);
|
|
void store_status (REGS *ssreg, U64 aaddr);
|
|
|
|
|
|
/* Function in module hdiagf18.c */
|
|
void ARCH_DEP( diagf18_call ) (int r1, int r2, REGS *regs);
|
|
|
|
/* Functions in module ipl.c */
|
|
int load_ipl (U16 lcss, U16 devnum, int cpu, int clear);
|
|
int ARCH_DEP( load_ipl ) (U16 lcss, U16 devnum, int cpu, int clear);
|
|
int system_reset ( const int target_mode, const bool clear, const bool ipl, const int cpu );
|
|
int ARCH_DEP( system_reset ) ( const int target_mode, const bool clear, const bool ipl, const int cpu );
|
|
int cpu_reset (REGS *regs);
|
|
int ARCH_DEP( cpu_reset ) (REGS *regs);
|
|
void initial_cpu_reset_all();
|
|
int initial_cpu_reset (REGS *regs);
|
|
int ARCH_DEP( initial_cpu_reset ) (REGS *regs);
|
|
int ARCH_DEP( common_load_begin ) (int cpu, int clear);
|
|
int ARCH_DEP( common_load_finish ) (REGS *regs);
|
|
|
|
void storage_clear(void);
|
|
void xstorage_clear(void);
|
|
|
|
|
|
/* Functions in module scedasd.c */
|
|
void set_sce_dir (char *path);
|
|
char *get_sce_dir ();
|
|
int load_main (char *fname, RADR startloc, int noisy );
|
|
int ARCH_DEP( load_main ) (char *fname, RADR startloc, int noisy );
|
|
int load_hmc (char *fname, int cpu, int clear);
|
|
int ARCH_DEP( load_hmc ) (char *fname, int cpu, int clear);
|
|
void ARCH_DEP( sclp_scedio_request ) (SCCB_HEADER *);
|
|
void ARCH_DEP( sclp_scedio_event ) (SCCB_HEADER *);
|
|
|
|
|
|
/* Functions in module scescsi.c */
|
|
void ARCH_DEP( sclp_hwl_request ) (SCCB_HEADER *);
|
|
void ARCH_DEP( sclp_hwl_event ) (SCCB_HEADER *);
|
|
void ARCH_DEP( sclp_sdias_request ) (SCCB_HEADER *);
|
|
void ARCH_DEP( sclp_sdias_event ) (SCCB_HEADER *);
|
|
void ARCH_DEP( sdias_store_status_clear ) (REGS *);
|
|
void ARCH_DEP( sdias_store_status ) (REGS *);
|
|
|
|
int support_boot (DEVBLK *);
|
|
int load_boot (DEVBLK *, int, int, int);
|
|
|
|
int hwldr_cmd (int, char **, char *);
|
|
int lddev_cmd (int, char **, char *);
|
|
|
|
|
|
/* Functions in module machchk.c */
|
|
int ARCH_DEP( present_mck_interrupt ) (REGS *regs, U64 *mcic, U32 *xdmg, RADR *fsta);
|
|
void machine_check_crwpend (void);
|
|
void build_attach_chrpt( DEVBLK *dev );
|
|
void build_detach_chrpt( DEVBLK *dev );
|
|
void build_chp_reset_chrpt( BYTE chpid, int solicited, int found );
|
|
int queue_channel_report( U32* crwarray, U32 crwcount );
|
|
U32 get_next_channel_report_word( REGS * );
|
|
|
|
|
|
/* Functions in module opcode.c */
|
|
void init_runtime_opcode_tables();
|
|
void init_regs_runtime_opcode_pointers( REGS* regs );
|
|
|
|
|
|
/* Functions in module hscmisc.c */
|
|
void ARCH_DEP( display_inst ) ( REGS* regs, BYTE* inst );
|
|
void ARCH_DEP( display_pgmint_inst )( REGS* regs, BYTE* inst );
|
|
|
|
|
|
/* Functions in module sie.c */
|
|
void ARCH_DEP( sie_exit ) (REGS *regs, int code);
|
|
void ARCH_DEP( diagnose_002 ) (REGS *regs, int r1, int r3);
|
|
|
|
|
|
/* Functions in module stack.c */
|
|
void ARCH_DEP( trap_x ) (int trap_is_trap4, REGS *regs, U32 trap_operand);
|
|
void ARCH_DEP( form_stack_entry ) (BYTE etype, VADR retna, VADR calla,
|
|
U32 csi, U32 pcnum, REGS *regs);
|
|
VADR ARCH_DEP( locate_stack_entry ) (int prinst, LSED *lsedptr,
|
|
REGS *regs);
|
|
void ARCH_DEP( stack_modify ) (VADR lsea, U32 m1, U32 m2, REGS *regs);
|
|
void ARCH_DEP( stack_extract ) (VADR lsea, int r1, int code, REGS *regs);
|
|
void ARCH_DEP( unstack_registers ) (int gtype, VADR lsea, int r1,
|
|
int r2, REGS *regs);
|
|
int ARCH_DEP( program_return_unstack ) (REGS *regs, RADR *lsedap, int *rc);
|
|
|
|
|
|
/* Functions in module trace.c */
|
|
CREG ARCH_DEP( trace_br ) (int amode, VADR ia, REGS *regs);
|
|
|
|
#if defined( _FEATURE_ZSIE )
|
|
U32 s390_trace_br (int amode, U32 ia, REGS *regs);
|
|
#endif
|
|
|
|
CREG ARCH_DEP( trace_bsg ) (U32 alet, VADR ia, REGS *regs);
|
|
CREG ARCH_DEP( trace_ssar ) (int ssair, U16 sasn, REGS *regs);
|
|
CREG ARCH_DEP( trace_pc ) (U32 pcea, REGS *regs);
|
|
CREG ARCH_DEP( trace_pr ) (REGS *newregs, REGS *regs);
|
|
CREG ARCH_DEP( trace_pt ) (int pti, U16 pasn, GREG gpr2, REGS *regs);
|
|
CREG ARCH_DEP( trace_tr ) (int r1, int r3, U32 op, REGS *regs);
|
|
CREG ARCH_DEP( trace_tg ) (int r1, int r3, U32 op, REGS *regs);
|
|
CREG ARCH_DEP( trace_ms ) (int br_ind, VADR ia, REGS *regs);
|
|
|
|
|
|
/* Functions in module plo.c */
|
|
int ARCH_DEP( plo_cl ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_clg ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_clgr ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_clx ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_cs ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csg ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csgr ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csx ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_dcs ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_dcsg ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_dcsgr ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_dcsx ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csst ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csstg ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csstgr ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csstx ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csdst ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csdstg ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csdstgr ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_csdstx ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_cstst ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_cststg ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_cststgr ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
int ARCH_DEP( plo_cststx ) (int r1, int r3, VADR effective_addr2, int b2,
|
|
VADR effective_addr4, int b4, REGS *regs);
|
|
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* DEF_INST */
|
|
/* (Define Instructions) */
|
|
/*-------------------------------------------------------------------*/
|
|
/* From this point onward to the end of file are all of the DEF_INST */
|
|
/* statements (possibly guarded with #if defined feature tests) that */
|
|
/* define all instructions currently supported by Hercules. For ease */
|
|
/* of maintainability please try to keep all of the below statements */
|
|
/* in FEATURE sequence. It is also NOT necessary to document which */
|
|
/* source file the code for the instruction exists in. A simple grep */
|
|
/* can determine that quite easily without cluttering this header. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* FEATUREs with STFL/STFLE facility bits defined */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#if defined( FEATURE_000_N3_INSTR_FACILITY )
|
|
DEF_INST( add_logical_carry );
|
|
DEF_INST( add_logical_carry_register );
|
|
DEF_INST( branch_relative_and_save_long );
|
|
DEF_INST( branch_relative_on_condition_long );
|
|
DEF_INST( divide_logical );
|
|
DEF_INST( divide_logical_register );
|
|
DEF_INST( extract_psw );
|
|
DEF_INST( load_address_relative_long );
|
|
DEF_INST( load_reversed );
|
|
DEF_INST( load_reversed_half );
|
|
DEF_INST( load_reversed_register );
|
|
DEF_INST( multiply_logical );
|
|
DEF_INST( multiply_logical_register );
|
|
DEF_INST( rotate_left_single_logical );
|
|
DEF_INST( set_addressing_mode_24 );
|
|
DEF_INST( set_addressing_mode_31 );
|
|
DEF_INST( store_facility_list );
|
|
DEF_INST( store_reversed );
|
|
DEF_INST( store_reversed_half );
|
|
DEF_INST( subtract_logical_borrow );
|
|
DEF_INST( subtract_logical_borrow_register );
|
|
DEF_INST( test_addressing_mode );
|
|
#endif
|
|
|
|
#if defined( FEATURE_003_DAT_ENHANCE_FACILITY_1 )
|
|
DEF_INST( compare_and_swap_and_purge_long );
|
|
DEF_INST( invalidate_dat_table_entry );
|
|
#endif
|
|
|
|
#if defined( FEATURE_006_ASN_LX_REUSE_FACILITY )
|
|
DEF_INST( extract_primary_asn_and_instance );
|
|
DEF_INST( extract_secondary_asn_and_instance );
|
|
DEF_INST( program_transfer_with_instance );
|
|
DEF_INST( set_secondary_asn_with_instance );
|
|
#endif
|
|
|
|
#if defined( FEATURE_007_STFL_EXTENDED_FACILITY )
|
|
DEF_INST( store_facility_list_extended );
|
|
#endif
|
|
|
|
#if defined( FEATURE_008_ENHANCED_DAT_FACILITY_1 )
|
|
DEF_INST( perform_frame_management_function );
|
|
#endif
|
|
|
|
#if defined( FEATURE_011_CONFIG_TOPOLOGY_FACILITY )
|
|
DEF_INST( perform_topology_function );
|
|
#endif
|
|
|
|
#if defined( FEATURE_016_EXT_TRANSL_FACILITY_2 )
|
|
DEF_INST( pack_ascii );
|
|
DEF_INST( pack_unicode );
|
|
DEF_INST( unpack_ascii );
|
|
DEF_INST( unpack_unicode );
|
|
DEF_INST( test_decimal );
|
|
DEF_INST( translate_two_to_two );
|
|
DEF_INST( translate_two_to_one );
|
|
DEF_INST( translate_one_to_two );
|
|
DEF_INST( translate_one_to_one );
|
|
DEF_INST( move_long_unicode );
|
|
DEF_INST( compare_logical_long_unicode );
|
|
#endif
|
|
|
|
#if defined( FEATURE_017_MSA_FACILITY )
|
|
DEF_INST( cipher_message );
|
|
DEF_INST( cipher_message_with_chaining );
|
|
DEF_INST( compute_intermediate_message_digest );
|
|
DEF_INST( compute_last_message_digest );
|
|
DEF_INST( compute_message_authentication_code );
|
|
#endif
|
|
|
|
#if defined( FEATURE_018_LONG_DISPL_INST_FACILITY )
|
|
DEF_INST( add_y );
|
|
DEF_INST( add_halfword_y );
|
|
DEF_INST( add_logical_y );
|
|
DEF_INST( and_immediate_y );
|
|
DEF_INST( and_y );
|
|
DEF_INST( compare_y );
|
|
DEF_INST( compare_and_swap_y );
|
|
DEF_INST( compare_double_and_swap_y );
|
|
DEF_INST( compare_halfword_y );
|
|
DEF_INST( compare_logical_y );
|
|
DEF_INST( compare_logical_immediate_y );
|
|
DEF_INST( compare_logical_characters_under_mask_y );
|
|
DEF_INST( convert_to_binary_y );
|
|
DEF_INST( convert_to_decimal_y );
|
|
DEF_INST( exclusive_or_immediate_y );
|
|
DEF_INST( exclusive_or_y );
|
|
DEF_INST( insert_character_y );
|
|
DEF_INST( insert_characters_under_mask_y );
|
|
DEF_INST( load_y );
|
|
DEF_INST( load_address_y );
|
|
DEF_INST( load_byte );
|
|
DEF_INST( load_byte_long );
|
|
DEF_INST( load_halfword_y );
|
|
DEF_INST( load_multiple_y );
|
|
DEF_INST( load_real_address_y );
|
|
DEF_INST( move_immediate_y );
|
|
DEF_INST( multiply_single_y );
|
|
DEF_INST( or_immediate_y );
|
|
DEF_INST( or_y );
|
|
DEF_INST( store_y );
|
|
DEF_INST( store_character_y );
|
|
DEF_INST( store_characters_under_mask_y );
|
|
DEF_INST( store_halfword_y );
|
|
DEF_INST( store_multiple_y );
|
|
DEF_INST( subtract_y );
|
|
DEF_INST( subtract_halfword_y );
|
|
DEF_INST( subtract_logical_y );
|
|
DEF_INST( test_under_mask_y );
|
|
#endif /* defined( FEATURE_018_LONG_DISPL_INST_FACILITY ) */
|
|
|
|
#if defined( FEATURE_018_LONG_DISPL_INST_FACILITY ) && defined( FEATURE_ACCESS_REGISTERS )
|
|
DEF_INST( load_access_multiple_y );
|
|
DEF_INST( store_access_multiple_y );
|
|
#endif
|
|
|
|
#if defined( FEATURE_018_LONG_DISPL_INST_FACILITY ) && defined( FEATURE_HEXADECIMAL_FLOATING_POINT )
|
|
DEF_INST( load_float_long_y );
|
|
DEF_INST( load_float_short_y );
|
|
DEF_INST( store_float_long_y );
|
|
DEF_INST( store_float_short_y );
|
|
#endif
|
|
|
|
#if defined( FEATURE_020_HFP_MULT_ADD_SUB_FACILITY )
|
|
DEF_INST( multiply_add_float_short_reg );
|
|
DEF_INST( multiply_add_float_long_reg );
|
|
DEF_INST( multiply_add_float_short );
|
|
DEF_INST( multiply_add_float_long );
|
|
DEF_INST( multiply_subtract_float_short_reg );
|
|
DEF_INST( multiply_subtract_float_long_reg );
|
|
DEF_INST( multiply_subtract_float_short );
|
|
DEF_INST( multiply_subtract_float_long );
|
|
#endif
|
|
|
|
#if defined( FEATURE_021_EXTENDED_IMMED_FACILITY )
|
|
DEF_INST( add_fullword_immediate );
|
|
DEF_INST( add_long_fullword_immediate );
|
|
DEF_INST( add_logical_fullword_immediate );
|
|
DEF_INST( add_logical_long_fullword_immediate );
|
|
DEF_INST( and_immediate_high_fullword );
|
|
DEF_INST( and_immediate_low_fullword );
|
|
DEF_INST( compare_fullword_immediate );
|
|
DEF_INST( compare_long_fullword_immediate );
|
|
DEF_INST( compare_logical_fullword_immediate );
|
|
DEF_INST( compare_logical_long_fullword_immediate );
|
|
DEF_INST( exclusive_or_immediate_high_fullword );
|
|
DEF_INST( exclusive_or_immediate_low_fullword );
|
|
DEF_INST( insert_immediate_high_fullword );
|
|
DEF_INST( insert_immediate_low_fullword );
|
|
DEF_INST( load_long_fullword_immediate );
|
|
DEF_INST( load_logical_immediate_high_fullword );
|
|
DEF_INST( load_logical_immediate_low_fullword );
|
|
DEF_INST( or_immediate_high_fullword );
|
|
DEF_INST( or_immediate_low_fullword );
|
|
DEF_INST( subtract_logical_fullword_immediate );
|
|
DEF_INST( subtract_logical_long_fullword_immediate );
|
|
DEF_INST( load_and_test );
|
|
DEF_INST( load_and_test_long );
|
|
DEF_INST( load_byte_register );
|
|
DEF_INST( load_long_byte_register );
|
|
DEF_INST( load_halfword_register );
|
|
DEF_INST( load_long_halfword_register );
|
|
DEF_INST( load_logical_character );
|
|
DEF_INST( load_logical_character_register );
|
|
DEF_INST( load_logical_long_character_register );
|
|
DEF_INST( load_logical_halfword );
|
|
DEF_INST( load_logical_halfword_register );
|
|
DEF_INST( load_logical_long_halfword_register );
|
|
DEF_INST( find_leftmost_one_long_register );
|
|
#endif /*defined( FEATURE_021_EXTENDED_IMMED_FACILITY )*/
|
|
|
|
#if defined( FEATURE_022_EXT_TRANSL_FACILITY_3 )
|
|
DEF_INST( convert_utf16_to_utf32 );
|
|
DEF_INST( convert_utf32_to_utf16 );
|
|
DEF_INST( convert_utf32_to_utf8 );
|
|
DEF_INST( convert_utf8_to_utf32 );
|
|
DEF_INST( search_string_unicode );
|
|
DEF_INST( translate_and_test_reverse );
|
|
#endif
|
|
|
|
#if defined( FEATURE_023_HFP_UNNORM_EXT_FACILITY )
|
|
DEF_INST( multiply_unnormal_float_long_to_ext_reg );
|
|
DEF_INST( multiply_unnormal_float_long_to_ext_low_reg );
|
|
DEF_INST( multiply_unnormal_float_long_to_ext_high_reg );
|
|
DEF_INST( multiply_add_unnormal_float_long_to_ext_reg );
|
|
DEF_INST( multiply_add_unnormal_float_long_to_ext_low_reg );
|
|
DEF_INST( multiply_add_unnormal_float_long_to_ext_high_reg );
|
|
DEF_INST( multiply_unnormal_float_long_to_ext );
|
|
DEF_INST( multiply_unnormal_float_long_to_ext_low );
|
|
DEF_INST( multiply_unnormal_float_long_to_ext_high );
|
|
DEF_INST( multiply_add_unnormal_float_long_to_ext );
|
|
DEF_INST( multiply_add_unnormal_float_long_to_ext_low );
|
|
DEF_INST( multiply_add_unnormal_float_long_to_ext_high );
|
|
#endif
|
|
|
|
#if defined( FEATURE_025_STORE_CLOCK_FAST_FACILITY )
|
|
DEF_INST( store_clock_fast );
|
|
#endif
|
|
|
|
#if defined( FEATURE_026_PARSING_ENHANCE_FACILITY )
|
|
DEF_INST( translate_and_test_extended );
|
|
DEF_INST( translate_and_test_reverse_extended );
|
|
#endif
|
|
|
|
#if defined( FEATURE_027_MVCOS_FACILITY )
|
|
DEF_INST( move_with_optional_specifications );
|
|
#endif
|
|
|
|
#if defined( FEATURE_028_TOD_CLOCK_STEER_FACILITY )
|
|
DEF_INST( perform_timing_facility_function );
|
|
#endif
|
|
|
|
#if defined( FEATURE_031_EXTRACT_CPU_TIME_FACILITY )
|
|
DEF_INST( extract_cpu_time );
|
|
#endif
|
|
|
|
#if defined( FEATURE_032_CSS_FACILITY )
|
|
DEF_INST( compare_and_swap_and_store );
|
|
#endif
|
|
|
|
#if defined( FEATURE_034_GEN_INST_EXTN_FACILITY )
|
|
DEF_INST( add_immediate_long_storage );
|
|
DEF_INST( add_immediate_storage );
|
|
DEF_INST( add_logical_with_signed_immediate );
|
|
DEF_INST( add_logical_with_signed_immediate_long );
|
|
DEF_INST( compare_and_branch_register );
|
|
DEF_INST( compare_and_branch_long_register );
|
|
DEF_INST( compare_and_branch_relative_register );
|
|
DEF_INST( compare_and_branch_relative_long_register );
|
|
DEF_INST( compare_and_trap_long_register );
|
|
DEF_INST( compare_and_trap_register );
|
|
DEF_INST( compare_halfword_immediate_halfword_storage );
|
|
DEF_INST( compare_halfword_immediate_long_storage );
|
|
DEF_INST( compare_halfword_immediate_storage );
|
|
DEF_INST( compare_halfword_long );
|
|
DEF_INST( compare_halfword_relative_long );
|
|
DEF_INST( compare_halfword_relative_long_long );
|
|
DEF_INST( compare_immediate_and_branch );
|
|
DEF_INST( compare_immediate_and_branch_long );
|
|
DEF_INST( compare_immediate_and_branch_relative );
|
|
DEF_INST( compare_immediate_and_branch_relative_long );
|
|
DEF_INST( compare_immediate_and_trap );
|
|
DEF_INST( compare_immediate_and_trap_long );
|
|
DEF_INST( compare_logical_and_branch_long_register );
|
|
DEF_INST( compare_logical_and_branch_register );
|
|
DEF_INST( compare_logical_and_branch_relative_long_register );
|
|
DEF_INST( compare_logical_and_branch_relative_register );
|
|
DEF_INST( compare_logical_and_trap_long_register );
|
|
DEF_INST( compare_logical_and_trap_register );
|
|
DEF_INST( compare_logical_immediate_and_branch );
|
|
DEF_INST( compare_logical_immediate_and_branch_long );
|
|
DEF_INST( compare_logical_immediate_and_branch_relative );
|
|
DEF_INST( compare_logical_immediate_and_branch_relative_long );
|
|
DEF_INST( compare_logical_immediate_and_trap_fullword );
|
|
DEF_INST( compare_logical_immediate_and_trap_long );
|
|
DEF_INST( compare_logical_immediate_fullword_storage );
|
|
DEF_INST( compare_logical_immediate_halfword_storage );
|
|
DEF_INST( compare_logical_immediate_long_storage );
|
|
DEF_INST( compare_logical_relative_long );
|
|
DEF_INST( compare_logical_relative_long_halfword );
|
|
DEF_INST( compare_logical_relative_long_long );
|
|
DEF_INST( compare_logical_relative_long_long_fullword );
|
|
DEF_INST( compare_logical_relative_long_long_halfword );
|
|
DEF_INST( compare_relative_long );
|
|
DEF_INST( compare_relative_long_long );
|
|
DEF_INST( compare_relative_long_long_fullword );
|
|
DEF_INST( extract_cpu_attribute );
|
|
DEF_INST( load_address_extended_y );
|
|
DEF_INST( load_and_test_long_fullword );
|
|
DEF_INST( load_halfword_relative_long );
|
|
DEF_INST( load_halfword_relative_long_long );
|
|
DEF_INST( load_logical_halfword_relative_long );
|
|
DEF_INST( load_logical_halfword_relative_long_long );
|
|
DEF_INST( load_logical_relative_long_long_fullword );
|
|
DEF_INST( load_relative_long );
|
|
DEF_INST( load_relative_long_long );
|
|
DEF_INST( load_relative_long_long_fullword );
|
|
DEF_INST( move_fullword_from_halfword_immediate );
|
|
DEF_INST( move_halfword_from_halfword_immediate );
|
|
DEF_INST( move_long_from_halfword_immediate );
|
|
DEF_INST( multiply_halfword_y );
|
|
DEF_INST( multiply_single_immediate_fullword );
|
|
DEF_INST( multiply_single_immediate_long_fullword );
|
|
DEF_INST( multiply_y );
|
|
DEF_INST( prefetch_data );
|
|
DEF_INST( prefetch_data_relative_long );
|
|
DEF_INST( rotate_then_and_selected_bits_long_reg );
|
|
DEF_INST( rotate_then_exclusive_or_selected_bits_long_reg );
|
|
DEF_INST( rotate_then_insert_selected_bits_long_reg );
|
|
DEF_INST( rotate_then_or_selected_bits_long_reg );
|
|
DEF_INST( store_halfword_relative_long );
|
|
DEF_INST( store_relative_long );
|
|
DEF_INST( store_relative_long_long );
|
|
#endif /*defined( FEATURE_034_GEN_INST_EXTN_FACILITY )*/
|
|
|
|
#if defined( FEATURE_035_EXECUTE_EXTN_FACILITY )
|
|
DEF_INST( execute_relative_long );
|
|
#endif
|
|
|
|
#if defined( FEATURE_037_FP_EXTENSION_FACILITY )
|
|
DEF_INST( convert_fix32_to_dfp_ext_reg );
|
|
DEF_INST( convert_fix32_to_dfp_long_reg );
|
|
DEF_INST( convert_u32_to_dfp_ext_reg );
|
|
DEF_INST( convert_u32_to_dfp_long_reg );
|
|
DEF_INST( convert_u64_to_dfp_ext_reg );
|
|
DEF_INST( convert_u64_to_dfp_long_reg );
|
|
DEF_INST( convert_dfp_ext_to_fix32_reg );
|
|
DEF_INST( convert_dfp_long_to_fix32_reg );
|
|
DEF_INST( convert_dfp_ext_to_u32_reg );
|
|
DEF_INST( convert_dfp_long_to_u32_reg );
|
|
DEF_INST( convert_dfp_ext_to_u64_reg );
|
|
DEF_INST( convert_dfp_long_to_u64_reg );
|
|
DEF_INST( convert_u32_to_bfp_ext_reg );
|
|
DEF_INST( convert_u32_to_bfp_long_reg );
|
|
DEF_INST( convert_u32_to_bfp_short_reg );
|
|
DEF_INST( convert_u64_to_bfp_ext_reg );
|
|
DEF_INST( convert_u64_to_bfp_long_reg );
|
|
DEF_INST( convert_u64_to_bfp_short_reg );
|
|
DEF_INST( convert_bfp_ext_to_u32_reg );
|
|
DEF_INST( convert_bfp_long_to_u32_reg );
|
|
DEF_INST( convert_bfp_short_to_u32_reg );
|
|
DEF_INST( convert_bfp_ext_to_u64_reg );
|
|
DEF_INST( convert_bfp_long_to_u64_reg );
|
|
DEF_INST( convert_bfp_short_to_u64_reg );
|
|
DEF_INST( set_bfp_rounding_mode_3bit );
|
|
#endif /* defined( FEATURE_037_FP_EXTENSION_FACILITY ) */
|
|
|
|
#if defined( FEATURE_040_LOAD_PROG_PARAM_FACILITY )
|
|
DEF_INST( load_program_parameter );
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#if defined( FEATURE_041_FPS_ENHANCEMENT_FACILITY )
|
|
|
|
#if defined( FEATURE_041_DFP_ROUNDING_FACILITY )
|
|
DEF_INST( set_dfp_rounding_mode );
|
|
#endif
|
|
|
|
#if defined( FEATURE_041_FPR_GR_TRANSFER_FACILITY )
|
|
DEF_INST( load_fpr_from_gr_long_reg );
|
|
DEF_INST( load_gr_from_fpr_long_reg );
|
|
#endif
|
|
|
|
#if defined( FEATURE_041_FPS_SIGN_HANDLING_FACILITY )
|
|
DEF_INST( copy_sign_fpr_long_reg );
|
|
DEF_INST( load_complement_fpr_long_reg );
|
|
DEF_INST( load_negative_fpr_long_reg );
|
|
DEF_INST( load_positive_fpr_long_reg );
|
|
#endif
|
|
|
|
#if defined( FEATURE_041_IEEE_EXCEPT_SIM_FACILITY )
|
|
DEF_INST( load_fpc_and_signal );
|
|
DEF_INST( set_fpc_and_signal );
|
|
#endif
|
|
|
|
#endif /* defined( FEATURE_041_FPS_ENHANCEMENT_FACILITY ) */
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#if defined( FEATURE_042_DFP_FACILITY )
|
|
DEF_INST( add_dfp_ext_reg );
|
|
DEF_INST( add_dfp_long_reg );
|
|
DEF_INST( compare_dfp_ext_reg );
|
|
DEF_INST( compare_dfp_long_reg );
|
|
DEF_INST( compare_and_signal_dfp_ext_reg );
|
|
DEF_INST( compare_and_signal_dfp_long_reg );
|
|
DEF_INST( compare_exponent_dfp_ext_reg );
|
|
DEF_INST( compare_exponent_dfp_long_reg );
|
|
DEF_INST( convert_fix64_to_dfp_ext_reg );
|
|
DEF_INST( convert_fix64_to_dfp_long_reg );
|
|
DEF_INST( convert_sbcd128_to_dfp_ext_reg );
|
|
DEF_INST( convert_sbcd64_to_dfp_long_reg );
|
|
DEF_INST( convert_ubcd128_to_dfp_ext_reg );
|
|
DEF_INST( convert_ubcd64_to_dfp_long_reg );
|
|
DEF_INST( convert_dfp_ext_to_fix64_reg );
|
|
DEF_INST( convert_dfp_long_to_fix64_reg );
|
|
DEF_INST( convert_dfp_ext_to_sbcd128_reg );
|
|
DEF_INST( convert_dfp_long_to_sbcd64_reg );
|
|
DEF_INST( convert_dfp_ext_to_ubcd128_reg );
|
|
DEF_INST( convert_dfp_long_to_ubcd64_reg );
|
|
DEF_INST( divide_dfp_ext_reg );
|
|
DEF_INST( divide_dfp_long_reg );
|
|
DEF_INST( extract_biased_exponent_dfp_ext_to_fix64_reg );
|
|
DEF_INST( extract_biased_exponent_dfp_long_to_fix64_reg );
|
|
DEF_INST( extract_significance_dfp_ext_reg );
|
|
DEF_INST( extract_significance_dfp_long_reg );
|
|
DEF_INST( insert_biased_exponent_fix64_to_dfp_ext_reg );
|
|
DEF_INST( insert_biased_exponent_fix64_to_dfp_long_reg );
|
|
DEF_INST( load_and_test_dfp_ext_reg );
|
|
DEF_INST( load_and_test_dfp_long_reg );
|
|
DEF_INST( load_fp_int_dfp_ext_reg );
|
|
DEF_INST( load_fp_int_dfp_long_reg );
|
|
DEF_INST( load_lengthened_dfp_long_to_ext_reg );
|
|
DEF_INST( load_lengthened_dfp_short_to_long_reg );
|
|
DEF_INST( load_rounded_dfp_ext_to_long_reg );
|
|
DEF_INST( load_rounded_dfp_long_to_short_reg );
|
|
DEF_INST( multiply_dfp_ext_reg );
|
|
DEF_INST( multiply_dfp_long_reg );
|
|
DEF_INST( quantize_dfp_ext_reg );
|
|
DEF_INST( quantize_dfp_long_reg );
|
|
DEF_INST( reround_dfp_ext_reg );
|
|
DEF_INST( reround_dfp_long_reg );
|
|
DEF_INST( shift_coefficient_left_dfp_ext );
|
|
DEF_INST( shift_coefficient_left_dfp_long );
|
|
DEF_INST( shift_coefficient_right_dfp_ext );
|
|
DEF_INST( shift_coefficient_right_dfp_long );
|
|
DEF_INST( subtract_dfp_ext_reg );
|
|
DEF_INST( subtract_dfp_long_reg );
|
|
DEF_INST( test_data_class_dfp_ext );
|
|
DEF_INST( test_data_class_dfp_long );
|
|
DEF_INST( test_data_class_dfp_short );
|
|
DEF_INST( test_data_group_dfp_ext );
|
|
DEF_INST( test_data_group_dfp_long );
|
|
DEF_INST( test_data_group_dfp_short );
|
|
#endif /*defined( FEATURE_042_DFP_FACILITY )*/
|
|
|
|
#if defined( FEATURE_044_PFPO_FACILITY )
|
|
DEF_INST( perform_floating_point_operation );
|
|
#endif
|
|
|
|
#if defined( FEATURE_045_DISTINCT_OPERANDS_FACILITY )
|
|
DEF_INST( add_distinct_register );
|
|
DEF_INST( add_distinct_long_register );
|
|
DEF_INST( add_distinct_halfword_immediate );
|
|
DEF_INST( add_distinct_long_halfword_immediate );
|
|
DEF_INST( add_logical_distinct_register );
|
|
DEF_INST( add_logical_distinct_long_register );
|
|
DEF_INST( add_logical_distinct_signed_halfword_immediate );
|
|
DEF_INST( add_logical_distinct_long_signed_halfword_immediate );
|
|
DEF_INST( and_distinct_register );
|
|
DEF_INST( and_distinct_long_register );
|
|
DEF_INST( exclusive_or_distinct_register );
|
|
DEF_INST( exclusive_or_distinct_long_register );
|
|
DEF_INST( or_distinct_register );
|
|
DEF_INST( or_distinct_long_register );
|
|
DEF_INST( shift_right_single_distinct );
|
|
DEF_INST( shift_left_single_distinct );
|
|
DEF_INST( shift_right_single_logical_distinct );
|
|
DEF_INST( shift_left_single_logical_distinct );
|
|
DEF_INST( subtract_distinct_register );
|
|
DEF_INST( subtract_distinct_long_register );
|
|
DEF_INST( subtract_logical_distinct_register );
|
|
DEF_INST( subtract_logical_distinct_long_register );
|
|
#endif /*defined( FEATURE_045_DISTINCT_OPERANDS_FACILITY )*/
|
|
|
|
#if defined( FEATURE_045_HIGH_WORD_FACILITY )
|
|
DEF_INST( add_high_high_high_register );
|
|
DEF_INST( add_high_high_low_register );
|
|
DEF_INST( add_high_immediate );
|
|
DEF_INST( add_logical_high_high_high_register );
|
|
DEF_INST( add_logical_high_high_low_register );
|
|
DEF_INST( add_logical_with_signed_immediate_high );
|
|
DEF_INST( add_logical_with_signed_immediate_high_n );
|
|
DEF_INST( branch_relative_on_count_high );
|
|
DEF_INST( compare_high_high_register );
|
|
DEF_INST( compare_high_low_register );
|
|
DEF_INST( compare_high_fullword );
|
|
DEF_INST( compare_high_immediate );
|
|
DEF_INST( compare_logical_high_high_register );
|
|
DEF_INST( compare_logical_high_low_register );
|
|
DEF_INST( compare_logical_high_fullword );
|
|
DEF_INST( compare_logical_high_immediate );
|
|
DEF_INST( load_byte_high );
|
|
DEF_INST( load_fullword_high );
|
|
DEF_INST( load_halfword_high );
|
|
DEF_INST( load_logical_character_high );
|
|
DEF_INST( load_logical_halfword_high );
|
|
DEF_INST( rotate_then_insert_selected_bits_high_long_reg );
|
|
DEF_INST( rotate_then_insert_selected_bits_low_long_reg );
|
|
DEF_INST( store_character_high );
|
|
DEF_INST( store_fullword_high );
|
|
DEF_INST( store_halfword_high );
|
|
DEF_INST( subtract_high_high_high_register );
|
|
DEF_INST( subtract_high_high_low_register );
|
|
DEF_INST( subtract_logical_high_high_high_register );
|
|
DEF_INST( subtract_logical_high_high_low_register );
|
|
#endif /*defined( FEATURE_045_HIGH_WORD_FACILITY )*/
|
|
|
|
#if defined( FEATURE_045_INTERLOCKED_ACCESS_FACILITY_1 )
|
|
DEF_INST( load_and_add );
|
|
DEF_INST( load_and_add_logical );
|
|
DEF_INST( load_and_and );
|
|
DEF_INST( load_and_exclusive_or );
|
|
DEF_INST( load_and_or );
|
|
DEF_INST( load_pair_disjoint );
|
|
DEF_INST( load_and_add_long );
|
|
DEF_INST( load_and_add_logical_long );
|
|
DEF_INST( load_and_and_long );
|
|
DEF_INST( load_and_exclusive_or_long );
|
|
DEF_INST( load_and_or_long );
|
|
DEF_INST( load_pair_disjoint_long );
|
|
#endif
|
|
|
|
#if defined( FEATURE_045_LOAD_STORE_ON_COND_FACILITY_1 )
|
|
DEF_INST( load_on_condition_register );
|
|
DEF_INST( load_on_condition_long_register );
|
|
DEF_INST( load_on_condition );
|
|
DEF_INST( load_on_condition_long );
|
|
DEF_INST( store_on_condition );
|
|
DEF_INST( store_on_condition_long );
|
|
#endif
|
|
|
|
#if defined( FEATURE_045_POPULATION_COUNT_FACILITY )
|
|
DEF_INST( population_count );
|
|
#endif
|
|
|
|
#if defined( FEATURE_048_DFP_ZONE_CONV_FACILITY )
|
|
DEF_INST( convert_zoned_to_dfp_ext );
|
|
DEF_INST( convert_zoned_to_dfp_long );
|
|
DEF_INST( convert_dfp_ext_to_zoned );
|
|
DEF_INST( convert_dfp_long_to_zoned );
|
|
#endif
|
|
|
|
#if defined( FEATURE_049_EXECUTION_HINT_FACILITY )
|
|
DEF_INST( branch_prediction_preload );
|
|
DEF_INST( branch_prediction_relative_preload );
|
|
DEF_INST( next_instruction_access_intent );
|
|
#endif
|
|
|
|
#if defined( FEATURE_049_LOAD_AND_TRAP_FACILITY )
|
|
DEF_INST( load_and_trap );
|
|
DEF_INST( load_long_and_trap );
|
|
DEF_INST( load_fullword_high_and_trap );
|
|
DEF_INST( load_logical_long_fullword_and_trap );
|
|
DEF_INST( load_logical_long_thirtyone_and_trap );
|
|
#endif
|
|
|
|
#if defined( FEATURE_049_MISC_INSTR_EXT_FACILITY_1 )
|
|
DEF_INST( compare_logical_and_trap );
|
|
DEF_INST( compare_logical_and_trap_long );
|
|
DEF_INST( rotate_then_insert_selected_bits_long_reg_n );
|
|
#endif
|
|
|
|
#if defined( FEATURE_049_PROCESSOR_ASSIST_FACILITY )
|
|
DEF_INST( perform_processor_assist );
|
|
#endif
|
|
|
|
#if defined( FEATURE_050_CONSTR_TRANSACT_FACILITY )
|
|
DEF_INST( transaction_begin_constrained );
|
|
#endif
|
|
|
|
#if defined( FEATURE_053_LOAD_STORE_ON_COND_FACILITY_2 )
|
|
DEF_INST( load_halfword_high_immediate_on_condition );
|
|
DEF_INST( load_halfword_immediate_on_condition );
|
|
DEF_INST( load_halfword_immediate_on_condition_grande );
|
|
DEF_INST( load_high_on_condition );
|
|
DEF_INST( load_high_on_condition_register );
|
|
DEF_INST( store_high_on_condition );
|
|
#endif
|
|
|
|
#if defined( FEATURE_053_LOAD_ZERO_RIGHTMOST_FACILITY )
|
|
DEF_INST( load_and_zero_rightmost_byte_grande );
|
|
DEF_INST( load_logical_and_zero_rightmost_byte );
|
|
DEF_INST( load_and_zero_rightmost_byte );
|
|
#endif
|
|
|
|
#if defined( FEATURE_057_MSA_EXTENSION_FACILITY_5 )
|
|
DEF_INST( perform_random_number_operation );
|
|
#endif
|
|
|
|
#if defined( FEATURE_058_MISC_INSTR_EXT_FACILITY_2 )
|
|
DEF_INST( branch_indirect_on_condition );
|
|
DEF_INST( add_long_halfword );
|
|
DEF_INST( subtract_long_halfword );
|
|
DEF_INST( multiply_long_register );
|
|
DEF_INST( multiply_long );
|
|
DEF_INST( multiply_long_halfword );
|
|
DEF_INST( multiply_single_register_cc );
|
|
DEF_INST( multiply_single_cc );
|
|
DEF_INST( multiply_single_long_register_cc );
|
|
DEF_INST( multiply_single_long_cc );
|
|
#endif
|
|
|
|
#if defined( FEATURE_061_MISC_INSTR_EXT_FACILITY_3 )
|
|
DEF_INST( and_register_with_complement );
|
|
DEF_INST( and_register_long_with_complement );
|
|
DEF_INST( nand_register );
|
|
DEF_INST( nand_register_long );
|
|
DEF_INST( not_xor_register );
|
|
DEF_INST( not_xor_register_long );
|
|
DEF_INST( nor_register );
|
|
DEF_INST( nor_register_long );
|
|
DEF_INST( or_register_with_complement );
|
|
DEF_INST( or_register_long_with_complement );
|
|
DEF_INST( select_register );
|
|
DEF_INST( select_register_long );
|
|
DEF_INST( select_fullword_high_register );
|
|
DEF_INST( move_right_to_left );
|
|
#endif
|
|
|
|
#if defined( FEATURE_066_RES_REF_BITS_MULT_FACILITY )
|
|
DEF_INST( reset_reference_bits_multiple );
|
|
#endif
|
|
|
|
#if defined( FEATURE_067_CPU_MEAS_COUNTER_FACILITY )
|
|
DEF_INST( extract_coprocessor_group_address );
|
|
DEF_INST( extract_cpu_counter );
|
|
DEF_INST( extract_peripheral_counter );
|
|
DEF_INST( load_cpu_counter_set_controls );
|
|
DEF_INST( load_peripheral_counter_set_controls );
|
|
DEF_INST( query_counter_information );
|
|
DEF_INST( set_cpu_counter );
|
|
DEF_INST( set_peripheral_counter );
|
|
#endif
|
|
|
|
#if defined( FEATURE_068_CPU_MEAS_SAMPLNG_FACILITY )
|
|
DEF_INST( load_sampling_controls );
|
|
DEF_INST( query_sampling_information );
|
|
#endif
|
|
|
|
#if defined( FEATURE_073_TRANSACT_EXEC_FACILITY)
|
|
DEF_INST( transaction_end );
|
|
DEF_INST( extract_transaction_nesting_depth );
|
|
DEF_INST( transaction_abort );
|
|
DEF_INST( nontransactional_store );
|
|
DEF_INST( transaction_begin );
|
|
#endif
|
|
|
|
#if defined( FEATURE_074_STORE_HYPER_INFO_FACILITY )
|
|
DEF_INST( store_hypervisor_information );
|
|
#endif
|
|
|
|
#if defined( FEATURE_076_MSA_EXTENSION_FACILITY_3 )
|
|
DEF_INST( perform_cryptographic_key_management_operation );
|
|
#endif
|
|
|
|
#if defined( FEATURE_077_MSA_EXTENSION_FACILITY_4 )
|
|
DEF_INST( perform_cryptographic_computation );
|
|
DEF_INST( cipher_message_with_cipher_feedback );
|
|
DEF_INST( cipher_message_with_output_feedback );
|
|
DEF_INST( cipher_message_with_counter );
|
|
#endif
|
|
|
|
#if defined( FEATURE_080_DFP_PACK_CONV_FACILITY )
|
|
DEF_INST(convert_packed_to_dfp_ext);
|
|
DEF_INST(convert_packed_to_dfp_long);
|
|
DEF_INST(convert_dfp_ext_to_packed);
|
|
DEF_INST(convert_dfp_long_to_packed);
|
|
#endif
|
|
|
|
#if defined( FEATURE_084_MISC_INSTR_EXT_FACILITY_4 )
|
|
DEF_INST( bit_deposit );
|
|
DEF_INST( bit_extract );
|
|
DEF_INST( count_leading_zeros );
|
|
DEF_INST( count_trailing_zeros );
|
|
DEF_INST( load_logical_indexed_address_shift_0 );
|
|
DEF_INST( load_logical_indexed_address_shift_1 );
|
|
DEF_INST( load_logical_indexed_address_shift_2 );
|
|
DEF_INST( load_logical_indexed_address_shift_3 );
|
|
DEF_INST( load_logical_indexed_address_shift_4 );
|
|
DEF_INST( load_indexed_address_shift_0 );
|
|
DEF_INST( load_indexed_address_shift_1 );
|
|
DEF_INST( load_indexed_address_shift_2 );
|
|
DEF_INST( load_indexed_address_shift_3 );
|
|
DEF_INST( load_indexed_address_shift_4 );
|
|
#endif
|
|
|
|
#if defined( FEATURE_129_ZVECTOR_FACILITY )
|
|
DEF_INST(vector_load_element_8);
|
|
DEF_INST(vector_load_element_16);
|
|
DEF_INST(vector_load_element_64);
|
|
DEF_INST(vector_load_element_32);
|
|
DEF_INST(vector_load_logical_element_and_zero);
|
|
DEF_INST(vector_load_and_replicate);
|
|
DEF_INST(vector_load);
|
|
DEF_INST(vector_load_to_block_boundary);
|
|
DEF_INST(vector_store_element_8);
|
|
DEF_INST(vector_store_element_16);
|
|
DEF_INST(vector_store_element_64);
|
|
DEF_INST(vector_store_element_32);
|
|
DEF_INST(vector_store);
|
|
DEF_INST(vector_gather_element_64);
|
|
DEF_INST(vector_gather_element_32);
|
|
DEF_INST(vector_scatter_element_64);
|
|
DEF_INST(vector_scatter_element_32);
|
|
DEF_INST(vector_load_gr_from_vr_element);
|
|
DEF_INST(vector_load_vr_element_from_gr);
|
|
DEF_INST(load_count_to_block_boundary);
|
|
DEF_INST(vector_element_shift_left);
|
|
DEF_INST(vector_element_rotate_left_logical);
|
|
DEF_INST(vector_load_multiple);
|
|
DEF_INST(vector_load_with_length);
|
|
DEF_INST(vector_element_shift_right_logical);
|
|
DEF_INST(vector_element_shift_right_arithmetic);
|
|
DEF_INST(vector_store_multiple);
|
|
DEF_INST(vector_store_with_length);
|
|
DEF_INST(vector_load_element_immediate_8);
|
|
DEF_INST(vector_load_element_immediate_16);
|
|
DEF_INST(vector_load_element_immediate_64);
|
|
DEF_INST(vector_load_element_immediate_32);
|
|
DEF_INST(vector_generate_byte_mask);
|
|
DEF_INST(vector_replicate_immediate);
|
|
DEF_INST(vector_generate_mask);
|
|
DEF_INST(vector_fp_test_data_class_immediate);
|
|
DEF_INST(vector_replicate);
|
|
DEF_INST(vector_population_count);
|
|
DEF_INST(vector_count_trailing_zeros);
|
|
DEF_INST(vector_count_leading_zeros);
|
|
DEF_INST(vector_load_vector);
|
|
DEF_INST(vector_isolate_string);
|
|
DEF_INST(vector_sign_extend_to_doubleword);
|
|
DEF_INST(vector_merge_low);
|
|
DEF_INST(vector_merge_high);
|
|
DEF_INST(vector_load_vr_from_grs_disjoint);
|
|
DEF_INST(vector_sum_across_word);
|
|
DEF_INST(vector_sum_across_doubleword);
|
|
DEF_INST(vector_checksum);
|
|
DEF_INST(vector_sum_across_quadword);
|
|
DEF_INST(vector_and);
|
|
DEF_INST(vector_and_with_complement);
|
|
DEF_INST(vector_or);
|
|
DEF_INST(vector_nor);
|
|
DEF_INST(vector_exclusive_or);
|
|
DEF_INST(vector_element_rotate_and_insert_under_mask);
|
|
DEF_INST(vector_element_rotate_left_logical_vector);
|
|
DEF_INST(vector_element_shift_left_vector);
|
|
DEF_INST(vector_element_shift_right_arithmetic_vector);
|
|
DEF_INST(vector_element_shift_right_logical_vector);
|
|
DEF_INST(vector_shift_left);
|
|
DEF_INST(vector_shift_left_by_byte);
|
|
DEF_INST(vector_shift_left_double_by_bit);
|
|
DEF_INST(vector_shift_left_double_by_byte);
|
|
DEF_INST(vector_shift_right_arithmetic);
|
|
DEF_INST(vector_shift_right_arithmetic_by_byte);
|
|
DEF_INST(vector_shift_right_double_by_bit);
|
|
DEF_INST(vector_shift_right_logical);
|
|
DEF_INST(vector_shift_right_logical_by_byte);
|
|
DEF_INST(vector_find_element_equal);
|
|
DEF_INST(vector_find_element_not_equal);
|
|
DEF_INST(vector_find_any_element_equal);
|
|
DEF_INST(vector_permute_doubleword_immediate);
|
|
DEF_INST(vector_string_range_compare);
|
|
DEF_INST(vector_string_search);
|
|
DEF_INST(vector_permute);
|
|
DEF_INST(vector_select);
|
|
DEF_INST(vector_fp_multiply_and_subtract);
|
|
DEF_INST(vector_fp_multiply_and_add);
|
|
DEF_INST(vector_pack);
|
|
DEF_INST(vector_pack_logical_saturate);
|
|
DEF_INST(vector_pack_saturate);
|
|
DEF_INST(vector_fp_negative_multiply_and_subtract);
|
|
DEF_INST(vector_fp_negative_multiply_and_add);
|
|
DEF_INST(vector_multiply_logical_high);
|
|
DEF_INST(vector_multiply_low);
|
|
DEF_INST(vector_multiply_high);
|
|
DEF_INST(vector_multiply_logical_even);
|
|
DEF_INST(vector_multiply_logical_odd);
|
|
DEF_INST(vector_multiply_even);
|
|
DEF_INST(vector_multiply_odd);
|
|
DEF_INST(vector_multiply_and_add_logical_high);
|
|
DEF_INST(vector_multiply_and_add_low);
|
|
DEF_INST(vector_multiply_and_add_high);
|
|
DEF_INST(vector_multiply_and_add_logical_even);
|
|
DEF_INST(vector_multiply_and_add_logical_odd);
|
|
DEF_INST(vector_multiply_and_add_even);
|
|
DEF_INST(vector_multiply_and_add_odd);
|
|
DEF_INST(vector_galois_field_multiply_sum);
|
|
DEF_INST(vector_add_with_carry_compute_carry);
|
|
DEF_INST(vector_add_with_carry);
|
|
DEF_INST(vector_galois_field_multiply_sum_and_accumulate);
|
|
DEF_INST(vector_subtract_with_borrow_compute_borrow_indication);
|
|
DEF_INST(vector_subtract_with_borrow_indication);
|
|
DEF_INST(vector_fp_convert_to_logical);
|
|
DEF_INST(vector_fp_convert_from_logical);
|
|
DEF_INST(vector_fp_convert_to_fixed);
|
|
DEF_INST(vector_fp_convert_from_fixed);
|
|
DEF_INST(vector_fp_load_lengthened);
|
|
DEF_INST(vector_fp_load_rounded);
|
|
DEF_INST(vector_load_fp_integer);
|
|
DEF_INST(vector_fp_compare_and_signal_scalar);
|
|
DEF_INST(vector_fp_compare_scalar);
|
|
DEF_INST(vector_fp_perform_sign_operation);
|
|
DEF_INST(vector_fp_square_root);
|
|
DEF_INST(vector_unpack_logical_low);
|
|
DEF_INST(vector_unpack_logical_high);
|
|
DEF_INST(vector_unpack_low);
|
|
DEF_INST(vector_unpack_high);
|
|
DEF_INST(vector_test_under_mask);
|
|
DEF_INST(vector_element_compare_logical);
|
|
DEF_INST(vector_element_compare);
|
|
DEF_INST(vector_load_complement);
|
|
DEF_INST(vector_load_positive);
|
|
DEF_INST(vector_fp_subtract);
|
|
DEF_INST(vector_fp_add);
|
|
DEF_INST(vector_fp_divide);
|
|
DEF_INST(vector_fp_multiply);
|
|
DEF_INST(vector_fp_compare_equal);
|
|
DEF_INST(vector_fp_compare_high_or_equal);
|
|
DEF_INST(vector_fp_compare_high);
|
|
DEF_INST(vector_average_logical);
|
|
DEF_INST(vector_add_compute_carry);
|
|
DEF_INST(vector_average);
|
|
DEF_INST(vector_add);
|
|
DEF_INST(vector_subtract_compute_borrow_indication);
|
|
DEF_INST(vector_subtract);
|
|
DEF_INST(vector_compare_equal);
|
|
DEF_INST(vector_compare_high_logical);
|
|
DEF_INST(vector_compare_high);
|
|
DEF_INST(vector_minimum_logical);
|
|
DEF_INST(vector_maximum_logical);
|
|
DEF_INST(vector_minimum);
|
|
DEF_INST(vector_maximum);
|
|
#endif
|
|
|
|
#if defined(FEATURE_134_ZVECTOR_PACK_DEC_FACILITY)
|
|
DEF_INST(vector_add_decimal);
|
|
DEF_INST(vector_compare_decimal);
|
|
DEF_INST(vector_convert_to_binary_32);
|
|
DEF_INST(vector_convert_to_binary_64);
|
|
DEF_INST(vector_convert_to_decimal_32);
|
|
DEF_INST(vector_convert_to_decimal_64);
|
|
DEF_INST(vector_divide_decimal);
|
|
DEF_INST(vector_load_immediate_decimal);
|
|
DEF_INST(vector_load_rightmost_with_length);
|
|
DEF_INST(vector_multiply_and_shift_decimal);
|
|
DEF_INST(vector_multiply_decimal);
|
|
DEF_INST(vector_pack_zoned);
|
|
DEF_INST(vector_perform_sign_operation_decimal);
|
|
DEF_INST(vector_remainder_decimal);
|
|
DEF_INST(vector_shift_and_divide_decimal);
|
|
DEF_INST(vector_shift_and_round_decimal);
|
|
DEF_INST(vector_shift_and_round_decimal_register);
|
|
DEF_INST(vector_store_rightmost_with_length);
|
|
DEF_INST(vector_subtract_decimal);
|
|
DEF_INST(vector_test_decimal);
|
|
DEF_INST(vector_unpack_zoned);
|
|
#endif
|
|
|
|
#if defined( FEATURE_135_ZVECTOR_ENH_FACILITY_1 )
|
|
DEF_INST(vector_bit_permute);
|
|
DEF_INST(vector_multiply_sum_logical);
|
|
DEF_INST(vector_not_exclusive_or);
|
|
DEF_INST(vector_nand);
|
|
DEF_INST(vector_or_with_complement);
|
|
DEF_INST(vector_fp_maximum);
|
|
DEF_INST(vector_fp_minimum);
|
|
#endif
|
|
|
|
#if defined( FEATURE_145_INS_REF_BITS_MULT_FACILITY )
|
|
DEF_INST( insert_reference_bits_multiple );
|
|
#endif
|
|
|
|
#if defined( FEATURE_148_VECTOR_ENH_FACILITY_2 )
|
|
DEF_INST(vector_load_byte_reversed_element_16);
|
|
DEF_INST(vector_load_byte_reversed_element_64);
|
|
DEF_INST(vector_load_byte_reversed_element_32);
|
|
DEF_INST(vector_load_byte_reversed_element_and_zero);
|
|
DEF_INST(vector_load_byte_reversed_element_and_replicate);
|
|
DEF_INST(vector_load_byte_reversed_elements);
|
|
DEF_INST(vector_load_elements_reversed);
|
|
DEF_INST(vector_store_byte_reversed_element_16);
|
|
DEF_INST(vector_store_byte_reversed_element_64);
|
|
DEF_INST(vector_store_byte_reversed_element_32);
|
|
DEF_INST(vector_store_byte_reversed_elements);
|
|
DEF_INST(vector_store_elements_reversed);
|
|
#endif
|
|
|
|
#if defined(FEATURE_152_VECT_PACKDEC_ENH_FACILITY)
|
|
DEF_INST(vector_load_rightmost_with_length_reg);
|
|
DEF_INST(vector_store_rightmost_with_length_reg);
|
|
#endif
|
|
|
|
#if defined(FEATURE_165_NNET_ASSIST_FACILITY)
|
|
DEF_INST(neural_network_processing_assist);
|
|
DEF_INST(vector_fp_convert_to_nnp);
|
|
DEF_INST(vector_fp_convert_and_lengthen_from_nnp_high);
|
|
DEF_INST(vector_fp_convert_from_nnp);
|
|
DEF_INST(vector_fp_convert_and_lengthen_from_nnp_low);
|
|
DEF_INST(vector_fp_convert_and_round_to_nnp);
|
|
#endif
|
|
|
|
#if defined(FEATURE_192_VECT_PACKDEC_ENH_2_FACILITY)
|
|
DEF_INST(vector_count_leading_zero_digits);
|
|
DEF_INST(vector_unpack_zoned_high);
|
|
DEF_INST(vector_unpack_zoned_low);
|
|
DEF_INST(vector_pack_zoned_register);
|
|
DEF_INST(decimal_scale_and_convert_to_hfp);
|
|
DEF_INST(decimal_scale_and_convert_and_split_to_hfp);
|
|
DEF_INST(vector_convert_hfp_to_scaled_decimal);
|
|
#endif
|
|
|
|
#if defined( FEATURE_193_BEAR_ENH_FACILITY )
|
|
DEF_INST( load_bear );
|
|
DEF_INST( store_bear );
|
|
DEF_INST( load_program_status_word_extended_y );
|
|
#endif
|
|
|
|
#if defined( FEATURE_198_VECTOR_ENH_FACILITY_3 )
|
|
DEF_INST( vector_generate_element_masks );
|
|
DEF_INST( vector_evaluate );
|
|
DEF_INST( vector_blend );
|
|
DEF_INST( vector_divide_logical );
|
|
DEF_INST( vector_remainder_logical );
|
|
DEF_INST( vector_divide );
|
|
DEF_INST( vector_remainder );
|
|
#endif
|
|
|
|
#if defined( FEATURE_199_VECT_PACKDEC_ENH_FACILITY_3 )
|
|
DEF_INST( vector_convert_to_decimal_128 );
|
|
DEF_INST( vector_convert_to_binary_128 );
|
|
DEF_INST( vector_test_zoned );
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* FEATUREs that DON'T have any facility bits defined */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#if defined( FEATURE_ACCESS_REGISTERS )
|
|
DEF_INST( purge_accesslist_lookaside_buffer );
|
|
DEF_INST( test_access );
|
|
DEF_INST( copy_access );
|
|
DEF_INST( extract_access_register );
|
|
DEF_INST( load_access_multiple );
|
|
DEF_INST( set_access_register );
|
|
DEF_INST( store_access_multiple );
|
|
#endif
|
|
|
|
#if defined( FEATURE_BASIC_STORAGE_KEYS )
|
|
DEF_INST( insert_storage_key );
|
|
DEF_INST( reset_reference_bit );
|
|
DEF_INST( set_storage_key );
|
|
#endif
|
|
|
|
#if defined( FEATURE_BIMODAL_ADDRESSING ) || defined( FEATURE_370_EXTENSION )
|
|
DEF_INST( branch_and_save_and_set_mode );
|
|
DEF_INST( branch_and_set_mode );
|
|
#endif
|
|
|
|
#if defined( FEATURE_BINARY_FLOATING_POINT )
|
|
DEF_INST( add_bfp_ext_reg );
|
|
DEF_INST( add_bfp_long );
|
|
DEF_INST( add_bfp_long_reg );
|
|
DEF_INST( add_bfp_short );
|
|
DEF_INST( add_bfp_short_reg );
|
|
DEF_INST( compare_and_signal_bfp_ext_reg );
|
|
DEF_INST( compare_and_signal_bfp_long );
|
|
DEF_INST( compare_and_signal_bfp_long_reg );
|
|
DEF_INST( compare_and_signal_bfp_short );
|
|
DEF_INST( compare_and_signal_bfp_short_reg );
|
|
DEF_INST( compare_bfp_ext_reg );
|
|
DEF_INST( compare_bfp_long );
|
|
DEF_INST( compare_bfp_long_reg );
|
|
DEF_INST( compare_bfp_short );
|
|
DEF_INST( compare_bfp_short_reg );
|
|
DEF_INST( convert_bfp_ext_to_fix32_reg );
|
|
DEF_INST( convert_bfp_ext_to_fix64_reg );
|
|
DEF_INST( convert_bfp_long_to_fix32_reg );
|
|
DEF_INST( convert_bfp_long_to_fix64_reg );
|
|
DEF_INST( convert_bfp_short_to_fix32_reg );
|
|
DEF_INST( convert_bfp_short_to_fix64_reg );
|
|
DEF_INST( convert_fix32_to_bfp_ext_reg );
|
|
DEF_INST( convert_fix32_to_bfp_long_reg );
|
|
DEF_INST( convert_fix32_to_bfp_short_reg );
|
|
DEF_INST( convert_fix64_to_bfp_ext_reg );
|
|
DEF_INST( convert_fix64_to_bfp_long_reg );
|
|
DEF_INST( convert_fix64_to_bfp_short_reg );
|
|
DEF_INST( divide_bfp_ext_reg );
|
|
DEF_INST( divide_bfp_long );
|
|
DEF_INST( divide_bfp_long_reg );
|
|
DEF_INST( divide_bfp_short );
|
|
DEF_INST( divide_bfp_short_reg );
|
|
DEF_INST( divide_integer_bfp_long_reg );
|
|
DEF_INST( divide_integer_bfp_short_reg );
|
|
DEF_INST( extract_fpc );
|
|
DEF_INST( load_and_test_bfp_ext_reg );
|
|
DEF_INST( load_and_test_bfp_long_reg );
|
|
DEF_INST( load_and_test_bfp_short_reg );
|
|
DEF_INST( load_complement_bfp_ext_reg );
|
|
DEF_INST( load_complement_bfp_long_reg );
|
|
DEF_INST( load_complement_bfp_short_reg );
|
|
DEF_INST( load_fp_int_bfp_ext_reg );
|
|
DEF_INST( load_fp_int_bfp_long_reg );
|
|
DEF_INST( load_fp_int_bfp_short_reg );
|
|
DEF_INST( load_fpc );
|
|
DEF_INST( load_lengthened_bfp_long_to_ext );
|
|
DEF_INST( load_lengthened_bfp_long_to_ext_reg );
|
|
DEF_INST( load_lengthened_bfp_short_to_ext );
|
|
DEF_INST( load_lengthened_bfp_short_to_ext_reg );
|
|
DEF_INST( load_lengthened_bfp_short_to_long );
|
|
DEF_INST( load_lengthened_bfp_short_to_long_reg );
|
|
DEF_INST( load_negative_bfp_ext_reg );
|
|
DEF_INST( load_negative_bfp_long_reg );
|
|
DEF_INST( load_negative_bfp_short_reg );
|
|
DEF_INST( load_positive_bfp_ext_reg );
|
|
DEF_INST( load_positive_bfp_long_reg );
|
|
DEF_INST( load_positive_bfp_short_reg );
|
|
DEF_INST( load_rounded_bfp_ext_to_long_reg );
|
|
DEF_INST( load_rounded_bfp_ext_to_short_reg );
|
|
DEF_INST( load_rounded_bfp_long_to_short_reg );
|
|
DEF_INST( multiply_add_bfp_long );
|
|
DEF_INST( multiply_add_bfp_long_reg );
|
|
DEF_INST( multiply_add_bfp_short );
|
|
DEF_INST( multiply_add_bfp_short_reg );
|
|
DEF_INST( multiply_bfp_ext_reg );
|
|
DEF_INST( multiply_bfp_long );
|
|
DEF_INST( multiply_bfp_long_reg );
|
|
DEF_INST( multiply_bfp_long_to_ext );
|
|
DEF_INST( multiply_bfp_long_to_ext_reg );
|
|
DEF_INST( multiply_bfp_short );
|
|
DEF_INST( multiply_bfp_short_reg );
|
|
DEF_INST( multiply_bfp_short_to_long );
|
|
DEF_INST( multiply_bfp_short_to_long_reg );
|
|
DEF_INST( multiply_subtract_bfp_long );
|
|
DEF_INST( multiply_subtract_bfp_long_reg );
|
|
DEF_INST( multiply_subtract_bfp_short );
|
|
DEF_INST( multiply_subtract_bfp_short_reg );
|
|
DEF_INST( set_bfp_rounding_mode_2bit );
|
|
DEF_INST( set_fpc );
|
|
DEF_INST( squareroot_bfp_ext_reg );
|
|
DEF_INST( squareroot_bfp_long );
|
|
DEF_INST( squareroot_bfp_long_reg );
|
|
DEF_INST( squareroot_bfp_short );
|
|
DEF_INST( squareroot_bfp_short_reg );
|
|
DEF_INST( store_fpc );
|
|
DEF_INST( subtract_bfp_ext_reg );
|
|
DEF_INST( subtract_bfp_long );
|
|
DEF_INST( subtract_bfp_long_reg );
|
|
DEF_INST( subtract_bfp_short );
|
|
DEF_INST( subtract_bfp_short_reg );
|
|
DEF_INST( test_data_class_bfp_ext );
|
|
DEF_INST( test_data_class_bfp_long );
|
|
DEF_INST( test_data_class_bfp_short );
|
|
#endif /*defined( FEATURE_BINARY_FLOATING_POINT )*/
|
|
|
|
#if defined( FEATURE_BRANCH_AND_SET_AUTHORITY )
|
|
DEF_INST( branch_and_set_authority );
|
|
#endif
|
|
|
|
#if defined( FEATURE_BROADCASTED_PURGING )
|
|
DEF_INST( compare_and_swap_and_purge );
|
|
#endif
|
|
|
|
#if defined( FEATURE_CANCEL_IO_FACILITY )
|
|
DEF_INST( cancel_subchannel );
|
|
#endif
|
|
|
|
#if defined( FEATURE_CHANNEL_SUBSYSTEM )
|
|
DEF_INST( clear_subchannel );
|
|
DEF_INST( halt_subchannel );
|
|
DEF_INST( modify_subchannel );
|
|
DEF_INST( resume_subchannel );
|
|
DEF_INST( set_address_limit );
|
|
DEF_INST( set_channel_monitor );
|
|
DEF_INST( reset_channel_path );
|
|
DEF_INST( start_subchannel );
|
|
DEF_INST( store_channel_path_status );
|
|
DEF_INST( store_channel_report_word );
|
|
DEF_INST( store_subchannel );
|
|
DEF_INST( test_pending_interruption );
|
|
DEF_INST( test_subchannel );
|
|
#endif /*defined( FEATURE_CHANNEL_SUBSYSTEM )*/
|
|
|
|
#if defined( FEATURE_CHANNEL_SWITCHING )
|
|
DEF_INST( connect_channel_set );
|
|
DEF_INST( disconnect_channel_set );
|
|
#endif
|
|
|
|
#if defined( FEATURE_CHECKSUM_INSTRUCTION )
|
|
DEF_INST( checksum );
|
|
#endif
|
|
|
|
#if defined( FEATURE_CHSC )
|
|
DEF_INST( channel_subsystem_call );
|
|
#endif
|
|
|
|
#if defined( FEATURE_CMPSC )
|
|
DEF_INST( cmpsc_2012 );
|
|
#endif
|
|
|
|
#if defined( FEATURE_COMPARE_AND_MOVE_EXTENDED )
|
|
DEF_INST( compare_logical_long_extended );
|
|
DEF_INST( move_long_extended );
|
|
#endif
|
|
|
|
#if defined( FEATURE_DAT_ENHANCEMENT_FACILITY_2 )
|
|
DEF_INST( load_page_table_entry_address );
|
|
#endif
|
|
|
|
#if defined( FEATURE_DUAL_ADDRESS_SPACE )
|
|
DEF_INST( extract_primary_asn );
|
|
DEF_INST( extract_secondary_asn );
|
|
DEF_INST( insert_address_space_control );
|
|
DEF_INST( insert_virtual_storage_key );
|
|
DEF_INST( load_address_space_parameters );
|
|
DEF_INST( move_to_primary );
|
|
DEF_INST( move_to_secondary );
|
|
DEF_INST( move_with_key );
|
|
DEF_INST( program_call );
|
|
DEF_INST( program_transfer );
|
|
DEF_INST( set_address_space_control );
|
|
DEF_INST( set_secondary_asn );
|
|
#endif
|
|
|
|
#if defined( FEATURE_ECPSVM )
|
|
DEF_INST( ecpsvm_basic_freex );
|
|
DEF_INST( ecpsvm_basic_fretx );
|
|
DEF_INST( ecpsvm_lock_page );
|
|
DEF_INST( ecpsvm_unlock_page );
|
|
DEF_INST( ecpsvm_decode_next_ccw );
|
|
DEF_INST( ecpsvm_free_ccwstor );
|
|
DEF_INST( ecpsvm_locate_vblock );
|
|
DEF_INST( ecpsvm_disp1 );
|
|
DEF_INST( ecpsvm_tpage );
|
|
DEF_INST( ecpsvm_tpage_lock );
|
|
DEF_INST( ecpsvm_inval_segtab );
|
|
DEF_INST( ecpsvm_inval_ptable );
|
|
DEF_INST( ecpsvm_decode_first_ccw );
|
|
DEF_INST( ecpsvm_dispatch_main );
|
|
DEF_INST( ecpsvm_locate_rblock );
|
|
DEF_INST( ecpsvm_comm_ccwproc );
|
|
DEF_INST( ecpsvm_unxlate_ccw );
|
|
DEF_INST( ecpsvm_disp2 );
|
|
DEF_INST( ecpsvm_store_level );
|
|
DEF_INST( ecpsvm_loc_chgshrpg );
|
|
DEF_INST( ecpsvm_extended_freex );
|
|
DEF_INST( ecpsvm_extended_fretx );
|
|
DEF_INST( ecpsvm_prefmach_assist );
|
|
#endif /*defined( FEATURE_ECPSVM )*/
|
|
|
|
#if defined( FEATURE_EMULATE_VM )
|
|
DEF_INST( inter_user_communication_vehicle );
|
|
#endif
|
|
|
|
#if defined( FEATURE_EXPANDED_STORAGE )
|
|
DEF_INST( page_in );
|
|
DEF_INST( page_out );
|
|
#endif
|
|
|
|
#if defined( FEATURE_EXTENDED_STORAGE_KEYS )
|
|
DEF_INST( insert_storage_key_extended );
|
|
DEF_INST( reset_reference_bit_extended );
|
|
DEF_INST( set_storage_key_extended );
|
|
#endif
|
|
|
|
#if defined( FEATURE_EXTENDED_TOD_CLOCK )
|
|
DEF_INST( set_clock_programmable_field );
|
|
DEF_INST( store_clock_extended );
|
|
#endif
|
|
|
|
#if defined( FEATURE_EXTENDED_TRANSLATION_FACILITY_1 )
|
|
DEF_INST( convert_utf16_to_utf8 );
|
|
DEF_INST( convert_utf8_to_utf16 );
|
|
DEF_INST( translate_extended );
|
|
#endif
|
|
|
|
#if defined( FEATURE_FPS_EXTENSIONS )
|
|
DEF_INST( convert_bfp_long_to_float_long_reg );
|
|
DEF_INST( convert_bfp_short_to_float_long_reg );
|
|
DEF_INST( convert_float_long_to_bfp_long_reg );
|
|
DEF_INST( convert_float_long_to_bfp_short_reg );
|
|
DEF_INST( load_float_ext_reg );
|
|
DEF_INST( load_zero_float_short_reg );
|
|
DEF_INST( load_zero_float_long_reg );
|
|
DEF_INST( load_zero_float_ext_reg );
|
|
#endif
|
|
|
|
#if defined( FEATURE_HEXADECIMAL_FLOATING_POINT )
|
|
DEF_INST( add_float_ext_reg );
|
|
DEF_INST( add_float_long );
|
|
DEF_INST( add_float_long_reg );
|
|
DEF_INST( add_float_short );
|
|
DEF_INST( add_float_short_reg );
|
|
DEF_INST( add_unnormal_float_long );
|
|
DEF_INST( add_unnormal_float_long_reg );
|
|
DEF_INST( add_unnormal_float_short );
|
|
DEF_INST( add_unnormal_float_short_reg );
|
|
DEF_INST( compare_float_long );
|
|
DEF_INST( compare_float_long_reg );
|
|
DEF_INST( compare_float_short );
|
|
DEF_INST( compare_float_short_reg );
|
|
DEF_INST( divide_float_ext_reg );
|
|
DEF_INST( divide_float_long );
|
|
DEF_INST( divide_float_long_reg );
|
|
DEF_INST( divide_float_short );
|
|
DEF_INST( divide_float_short_reg );
|
|
DEF_INST( halve_float_long_reg );
|
|
DEF_INST( halve_float_short_reg );
|
|
DEF_INST( load_and_test_float_long_reg );
|
|
DEF_INST( load_and_test_float_short_reg );
|
|
DEF_INST( load_complement_float_long_reg );
|
|
DEF_INST( load_complement_float_short_reg );
|
|
DEF_INST( load_float_long );
|
|
DEF_INST( load_float_long_reg );
|
|
DEF_INST( load_float_short );
|
|
DEF_INST( load_float_short_reg );
|
|
DEF_INST( load_negative_float_long_reg );
|
|
DEF_INST( load_negative_float_short_reg );
|
|
DEF_INST( load_positive_float_long_reg );
|
|
DEF_INST( load_positive_float_short_reg );
|
|
DEF_INST( load_rounded_float_long_reg );
|
|
DEF_INST( load_rounded_float_short_reg );
|
|
DEF_INST( multiply_float_ext_reg );
|
|
DEF_INST( multiply_float_long );
|
|
DEF_INST( multiply_float_long_reg );
|
|
DEF_INST( multiply_float_long_to_ext );
|
|
DEF_INST( multiply_float_long_to_ext_reg );
|
|
DEF_INST( multiply_float_short_to_long );
|
|
DEF_INST( multiply_float_short_to_long_reg );
|
|
DEF_INST( store_float_long );
|
|
DEF_INST( store_float_short );
|
|
DEF_INST( subtract_float_ext_reg );
|
|
DEF_INST( subtract_float_long );
|
|
DEF_INST( subtract_float_long_reg );
|
|
DEF_INST( subtract_float_short );
|
|
DEF_INST( subtract_float_short_reg );
|
|
DEF_INST( subtract_unnormal_float_long );
|
|
DEF_INST( subtract_unnormal_float_long_reg );
|
|
DEF_INST( subtract_unnormal_float_short );
|
|
DEF_INST( subtract_unnormal_float_short_reg );
|
|
#endif /* defined( FEATURE_HEXADECIMAL_FLOATING_POINT ) */
|
|
|
|
#if defined( FEATURE_HFP_EXTENSIONS )
|
|
DEF_INST( load_lengthened_float_short_to_long_reg );
|
|
DEF_INST( load_lengthened_float_long_to_ext_reg );
|
|
DEF_INST( load_lengthened_float_short_to_ext_reg );
|
|
DEF_INST( squareroot_float_ext_reg );
|
|
DEF_INST( multiply_float_short_reg );
|
|
DEF_INST( load_positive_float_ext_reg );
|
|
DEF_INST( load_negative_float_ext_reg );
|
|
DEF_INST( load_and_test_float_ext_reg );
|
|
DEF_INST( load_complement_float_ext_reg );
|
|
DEF_INST( load_rounded_float_ext_to_short_reg );
|
|
DEF_INST( load_fp_int_float_ext_reg );
|
|
DEF_INST( compare_float_ext_reg );
|
|
DEF_INST( load_fp_int_float_short_reg );
|
|
DEF_INST( load_fp_int_float_long_reg );
|
|
DEF_INST( convert_fixed_to_float_short_reg );
|
|
DEF_INST( convert_fixed_to_float_long_reg );
|
|
DEF_INST( convert_fixed_to_float_ext_reg );
|
|
DEF_INST( convert_float_short_to_fixed_reg );
|
|
DEF_INST( convert_float_long_to_fixed_reg );
|
|
DEF_INST( convert_float_ext_to_fixed_reg );
|
|
DEF_INST( load_lengthened_float_short_to_long );
|
|
DEF_INST( load_lengthened_float_long_to_ext );
|
|
DEF_INST( load_lengthened_float_short_to_ext );
|
|
DEF_INST( squareroot_float_short );
|
|
DEF_INST( squareroot_float_long );
|
|
DEF_INST( multiply_float_short );
|
|
#endif /*defined( FEATURE_HFP_EXTENSIONS )*/
|
|
|
|
#if defined( FEATURE_IMMEDIATE_AND_RELATIVE )
|
|
DEF_INST( add_halfword_immediate );
|
|
DEF_INST( branch_relative_and_save );
|
|
DEF_INST( branch_relative_on_condition );
|
|
DEF_INST( branch_relative_on_count );
|
|
DEF_INST( branch_relative_on_index_high );
|
|
DEF_INST( branch_relative_on_index_low_or_equal );
|
|
DEF_INST( compare_halfword_immediate );
|
|
DEF_INST( load_halfword_immediate );
|
|
DEF_INST( multiply_halfword_immediate );
|
|
DEF_INST( multiply_single );
|
|
DEF_INST( multiply_single_register );
|
|
DEF_INST( test_under_mask_high );
|
|
DEF_INST( test_under_mask_low );
|
|
#endif
|
|
|
|
#if defined( FEATURE_SIE )
|
|
DEF_INST( start_interpretive_execution );
|
|
#endif
|
|
|
|
#if defined( FEATURE_IO_ASSIST )
|
|
DEF_INST( test_pending_zone_interrupt );
|
|
#endif
|
|
|
|
#if defined( FEATURE_LINKAGE_STACK )
|
|
DEF_INST( branch_and_stack );
|
|
DEF_INST( extract_stacked_registers );
|
|
DEF_INST( extract_stacked_state );
|
|
DEF_INST( modify_stacked_state );
|
|
DEF_INST( program_return );
|
|
DEF_INST( trap2 );
|
|
DEF_INST( trap4 );
|
|
#endif
|
|
|
|
#if defined( FEATURE_LOCK_PAGE )
|
|
DEF_INST( lock_page );
|
|
#endif
|
|
|
|
#if defined( FEATURE_MOVE_PAGE_FACILITY_2 )
|
|
DEF_INST( move_page );
|
|
DEF_INST( invalidate_expanded_storage_block_entry );
|
|
#endif
|
|
|
|
#if defined( FEATURE_NEW_ZARCH_ONLY_INSTRUCTIONS ) // 'N' instructions
|
|
DEF_INST( add_logical_carry_long );
|
|
DEF_INST( add_logical_carry_long_register );
|
|
DEF_INST( add_logical_long );
|
|
DEF_INST( add_logical_long_fullword );
|
|
DEF_INST( add_logical_long_fullword_register );
|
|
DEF_INST( add_logical_long_register );
|
|
DEF_INST( add_long );
|
|
DEF_INST( add_long_fullword );
|
|
DEF_INST( add_long_fullword_register );
|
|
DEF_INST( add_long_halfword_immediate );
|
|
DEF_INST( add_long_register );
|
|
DEF_INST( and_immediate_high_high );
|
|
DEF_INST( and_immediate_high_low );
|
|
DEF_INST( and_immediate_low_high );
|
|
DEF_INST( and_immediate_low_low );
|
|
DEF_INST( and_long );
|
|
DEF_INST( and_long_register );
|
|
DEF_INST( branch_on_count_long );
|
|
DEF_INST( branch_on_count_long_register );
|
|
DEF_INST( branch_on_index_high_long );
|
|
DEF_INST( branch_on_index_low_or_equal_long );
|
|
DEF_INST( branch_relative_on_count_long );
|
|
DEF_INST( branch_relative_on_index_high_long );
|
|
DEF_INST( branch_relative_on_index_low_or_equal_long );
|
|
DEF_INST( compare_and_swap_long );
|
|
DEF_INST( compare_double_and_swap_long );
|
|
DEF_INST( compare_logical_characters_under_mask_high );
|
|
DEF_INST( compare_logical_long );
|
|
DEF_INST( compare_logical_long_fullword );
|
|
DEF_INST( compare_logical_long_fullword_register );
|
|
DEF_INST( compare_logical_long_register );
|
|
DEF_INST( compare_long );
|
|
DEF_INST( compare_long_fullword );
|
|
DEF_INST( compare_long_fullword_register );
|
|
DEF_INST( compare_long_halfword_immediate );
|
|
DEF_INST( compare_long_register );
|
|
DEF_INST( convert_fix64_to_float_ext_reg );
|
|
DEF_INST( convert_fix64_to_float_long_reg );
|
|
DEF_INST( convert_fix64_to_float_short_reg );
|
|
DEF_INST( convert_float_ext_to_fix64_reg );
|
|
DEF_INST( convert_float_long_to_fix64_reg );
|
|
DEF_INST( convert_float_short_to_fix64_reg );
|
|
DEF_INST( convert_to_binary_long );
|
|
DEF_INST( convert_to_decimal_long );
|
|
DEF_INST( divide_logical_long );
|
|
DEF_INST( divide_logical_long_register );
|
|
DEF_INST( divide_single_long );
|
|
DEF_INST( divide_single_long_fullword );
|
|
DEF_INST( divide_single_long_fullword_register );
|
|
DEF_INST( divide_single_long_register );
|
|
DEF_INST( exclusive_or_long );
|
|
DEF_INST( exclusive_or_long_register );
|
|
DEF_INST( extract_and_set_extended_authority );
|
|
DEF_INST( extract_stacked_registers_long );
|
|
DEF_INST( insert_characters_under_mask_high );
|
|
DEF_INST( insert_immediate_high_high );
|
|
DEF_INST( insert_immediate_high_low );
|
|
DEF_INST( insert_immediate_low_high );
|
|
DEF_INST( insert_immediate_low_low );
|
|
DEF_INST( load_and_test_long_fullword_register );
|
|
DEF_INST( load_and_test_long_register );
|
|
DEF_INST( load_complement_long_fullword_register );
|
|
DEF_INST( load_complement_long_register );
|
|
DEF_INST( load_control_long );
|
|
DEF_INST( load_logical_immediate_high_high );
|
|
DEF_INST( load_logical_immediate_high_low );
|
|
DEF_INST( load_logical_immediate_low_high );
|
|
DEF_INST( load_logical_immediate_low_low );
|
|
DEF_INST( load_logical_long_character );
|
|
DEF_INST( load_logical_long_fullword );
|
|
DEF_INST( load_logical_long_fullword_register );
|
|
DEF_INST( load_logical_long_halfword );
|
|
DEF_INST( load_logical_long_thirtyone );
|
|
DEF_INST( load_logical_long_thirtyone_register );
|
|
DEF_INST( load_long );
|
|
DEF_INST( load_long_fullword );
|
|
DEF_INST( load_long_fullword_register );
|
|
DEF_INST( load_long_halfword );
|
|
DEF_INST( load_long_halfword_immediate );
|
|
DEF_INST( load_long_register );
|
|
DEF_INST( load_multiple_disjoint );
|
|
DEF_INST( load_multiple_high );
|
|
DEF_INST( load_multiple_long );
|
|
DEF_INST( load_negative_long_fullword_register );
|
|
DEF_INST( load_negative_long_register );
|
|
DEF_INST( load_pair_from_quadword );
|
|
DEF_INST( load_positive_long_fullword_register );
|
|
DEF_INST( load_positive_long_register );
|
|
DEF_INST( load_program_status_word_extended );
|
|
DEF_INST( load_real_address_long );
|
|
DEF_INST( load_reversed_long );
|
|
DEF_INST( load_reversed_long_register );
|
|
DEF_INST( load_using_real_address_long );
|
|
DEF_INST( multiply_logical_long );
|
|
DEF_INST( multiply_logical_long_register );
|
|
DEF_INST( multiply_long_halfword_immediate );
|
|
DEF_INST( multiply_single_long );
|
|
DEF_INST( multiply_single_long_fullword );
|
|
DEF_INST( multiply_single_long_fullword_register );
|
|
DEF_INST( multiply_single_long_register );
|
|
DEF_INST( or_immediate_high_high );
|
|
DEF_INST( or_immediate_high_low );
|
|
DEF_INST( or_immediate_low_high );
|
|
DEF_INST( or_immediate_low_low );
|
|
DEF_INST( or_long );
|
|
DEF_INST( or_long_register );
|
|
DEF_INST( rotate_left_single_logical_long );
|
|
DEF_INST( set_addressing_mode_64 );
|
|
DEF_INST( shift_left_single_logical_long );
|
|
DEF_INST( shift_left_single_long );
|
|
DEF_INST( shift_right_single_logical_long );
|
|
DEF_INST( shift_right_single_long );
|
|
DEF_INST( store_characters_under_mask_high );
|
|
DEF_INST( store_control_long );
|
|
DEF_INST( store_long );
|
|
DEF_INST( store_multiple_high );
|
|
DEF_INST( store_multiple_long );
|
|
DEF_INST( store_pair_to_quadword );
|
|
DEF_INST( store_real_address );
|
|
DEF_INST( store_reversed_long );
|
|
DEF_INST( store_using_real_address_long );
|
|
DEF_INST( subtract_logical_borrow_long );
|
|
DEF_INST( subtract_logical_borrow_long_register );
|
|
DEF_INST( subtract_logical_long );
|
|
DEF_INST( subtract_logical_long_fullword );
|
|
DEF_INST( subtract_logical_long_fullword_register );
|
|
DEF_INST( subtract_logical_long_register );
|
|
DEF_INST( subtract_long );
|
|
DEF_INST( subtract_long_fullword );
|
|
DEF_INST( subtract_long_fullword_register );
|
|
DEF_INST( subtract_long_register );
|
|
DEF_INST( test_under_mask_high_high );
|
|
DEF_INST( test_under_mask_high_low );
|
|
DEF_INST( trace_long );
|
|
#endif /* defined( FEATURE_NEW_ZARCH_ONLY_INSTRUCTIONS ) */
|
|
|
|
#if defined( FEATURE_PERFORM_LOCKED_OPERATION )
|
|
DEF_INST( perform_locked_operation );
|
|
#endif
|
|
|
|
#if defined( FEATURE_QUEUED_DIRECT_IO )
|
|
DEF_INST( signal_adapter );
|
|
|
|
#if defined( FEATURE_QEBSM )
|
|
DEF_INST( set_queue_buffer_state );
|
|
DEF_INST( extract_queue_buffer_state );
|
|
#endif
|
|
|
|
#if defined( FEATURE_SVS )
|
|
DEF_INST( set_vector_summary );
|
|
#endif
|
|
#endif
|
|
|
|
#if defined( FEATURE_REGION_RELOCATE )
|
|
DEF_INST( store_zone_parameter );
|
|
DEF_INST( set_zone_parameter );
|
|
#endif
|
|
|
|
#if defined( FEATURE_RESUME_PROGRAM )
|
|
DEF_INST( resume_program );
|
|
#endif
|
|
|
|
#if defined( FEATURE_S370_CHANNEL )
|
|
DEF_INST( start_io );
|
|
DEF_INST( test_io );
|
|
DEF_INST( halt_io );
|
|
DEF_INST( test_channel );
|
|
DEF_INST( store_channel_id );
|
|
#endif
|
|
|
|
#if defined( FEATURE_S370_S390_VECTOR_FACILITY )
|
|
DEF_INST( v_test_vmr );
|
|
DEF_INST( v_complement_vmr );
|
|
DEF_INST( v_count_left_zeros_in_vmr );
|
|
DEF_INST( v_count_ones_in_vmr );
|
|
DEF_INST( v_extract_vct );
|
|
DEF_INST( v_extract_vector_modes );
|
|
DEF_INST( v_restore_vr );
|
|
DEF_INST( v_save_changed_vr );
|
|
DEF_INST( v_save_vr );
|
|
DEF_INST( v_load_vmr );
|
|
DEF_INST( v_load_vmr_complement );
|
|
DEF_INST( v_store_vmr );
|
|
DEF_INST( v_and_to_vmr );
|
|
DEF_INST( v_or_to_vmr );
|
|
DEF_INST( v_exclusive_or_to_vmr );
|
|
DEF_INST( v_save_vsr );
|
|
DEF_INST( v_save_vmr );
|
|
DEF_INST( v_restore_vsr );
|
|
DEF_INST( v_restore_vmr );
|
|
DEF_INST( v_load_vct_from_address );
|
|
DEF_INST( v_clear_vr );
|
|
DEF_INST( v_set_vector_mask_mode );
|
|
DEF_INST( v_load_vix_from_address );
|
|
DEF_INST( v_store_vector_parameters );
|
|
DEF_INST( v_save_vac );
|
|
DEF_INST( v_restore_vac );
|
|
#endif /* defined( FEATURE_S370_S390_VECTOR_FACILITY ) */
|
|
|
|
#if defined( FEATURE_SERVICE_PROCESSOR )
|
|
DEF_INST( service_call );
|
|
#endif
|
|
|
|
#if defined( FEATURE_SET_ADDRESS_SPACE_CONTROL_FAST )
|
|
DEF_INST( set_address_space_control_fast );
|
|
#endif
|
|
|
|
#if defined( FEATURE_SQUARE_ROOT )
|
|
DEF_INST( squareroot_float_long_reg );
|
|
DEF_INST( squareroot_float_short_reg );
|
|
#endif
|
|
|
|
#if defined( FEATURE_STORE_SYSTEM_INFORMATION )
|
|
DEF_INST( store_system_information );
|
|
#endif
|
|
|
|
#if defined( FEATURE_STRING_INSTRUCTION )
|
|
DEF_INST( compare_logical_string );
|
|
DEF_INST( compare_until_substring_equal );
|
|
DEF_INST( move_string );
|
|
DEF_INST( search_string );
|
|
#endif
|
|
|
|
#if defined( FEATURE_SUBSPACE_GROUP )
|
|
DEF_INST( branch_in_subspace_group );
|
|
#endif
|
|
|
|
#if defined( FEATURE_TCPIP_EXTENSION )
|
|
DEF_INST( tcpip );
|
|
#endif
|
|
|
|
#if defined( FEATURE_ZVM_ESSA )
|
|
DEF_INST( extract_and_set_storage_attributes );
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Instructions NOT associated with ANY facility or feature */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
DEF_INST( execute_e3________xx );
|
|
DEF_INST( execute_eb________xx );
|
|
DEF_INST( execute_ec________xx );
|
|
DEF_INST( execute_ed________xx );
|
|
|
|
DEF_INST( add );
|
|
DEF_INST( add_decimal );
|
|
DEF_INST( add_frr );
|
|
DEF_INST( add_halfword );
|
|
DEF_INST( add_logical );
|
|
DEF_INST( add_logical_register );
|
|
DEF_INST( add_register );
|
|
DEF_INST( and );
|
|
DEF_INST( and_character );
|
|
DEF_INST( and_immediate );
|
|
DEF_INST( and_register );
|
|
DEF_INST( branch_and_link );
|
|
DEF_INST( branch_and_link_register );
|
|
DEF_INST( branch_and_save );
|
|
DEF_INST( branch_and_save_register );
|
|
DEF_INST( branch_on_condition );
|
|
DEF_INST( branch_on_condition_register );
|
|
DEF_INST( branch_on_count );
|
|
DEF_INST( branch_on_count_register );
|
|
DEF_INST( branch_on_index_high );
|
|
DEF_INST( branch_on_index_low_or_equal );
|
|
DEF_INST( compare );
|
|
DEF_INST( compare_and_form_codeword );
|
|
DEF_INST( compare_and_swap );
|
|
DEF_INST( compare_decimal );
|
|
DEF_INST( compare_double_and_swap );
|
|
DEF_INST( compare_halfword );
|
|
DEF_INST( compare_logical );
|
|
DEF_INST( compare_logical_character );
|
|
DEF_INST( compare_logical_character_long );
|
|
DEF_INST( compare_logical_characters_under_mask );
|
|
DEF_INST( compare_logical_immediate );
|
|
DEF_INST( compare_logical_register );
|
|
DEF_INST( compare_register );
|
|
DEF_INST( convert_to_binary );
|
|
DEF_INST( convert_to_decimal );
|
|
DEF_INST( diagnose );
|
|
DEF_INST( divide );
|
|
DEF_INST( divide_decimal );
|
|
DEF_INST( divide_register );
|
|
DEF_INST( edit_x_edit_and_mark );
|
|
DEF_INST( exclusive_or );
|
|
DEF_INST( exclusive_or_character );
|
|
DEF_INST( exclusive_or_immediate );
|
|
DEF_INST( exclusive_or_register );
|
|
DEF_INST( execute );
|
|
DEF_INST( fix_page );
|
|
DEF_INST( insert_character );
|
|
DEF_INST( insert_characters_under_mask );
|
|
DEF_INST( insert_program_mask );
|
|
DEF_INST( insert_psw_key );
|
|
DEF_INST( invalidate_page_table_entry );
|
|
DEF_INST( load );
|
|
DEF_INST( load_address );
|
|
DEF_INST( load_address_extended );
|
|
DEF_INST( load_and_test_register );
|
|
DEF_INST( load_complement_register );
|
|
DEF_INST( load_control );
|
|
DEF_INST( load_halfword );
|
|
DEF_INST( load_multiple );
|
|
DEF_INST( load_negative_register );
|
|
DEF_INST( load_positive_register );
|
|
DEF_INST( load_program_status_word );
|
|
DEF_INST( load_real_address );
|
|
DEF_INST( load_register );
|
|
DEF_INST( load_using_real_address );
|
|
DEF_INST( monitor_call );
|
|
DEF_INST( move_character );
|
|
DEF_INST( move_immediate );
|
|
DEF_INST( move_inverse );
|
|
DEF_INST( move_long );
|
|
DEF_INST( move_numerics );
|
|
DEF_INST( move_with_destination_key );
|
|
DEF_INST( move_with_offset );
|
|
DEF_INST( move_with_source_key );
|
|
DEF_INST( move_zones );
|
|
DEF_INST( multiply );
|
|
DEF_INST( multiply_decimal );
|
|
DEF_INST( multiply_halfword );
|
|
DEF_INST( multiply_register );
|
|
DEF_INST( obtain_cms_lock );
|
|
DEF_INST( obtain_local_lock );
|
|
DEF_INST( operation_exception );
|
|
DEF_INST( or );
|
|
DEF_INST( or_character );
|
|
DEF_INST( or_immediate );
|
|
DEF_INST( or_register );
|
|
DEF_INST( pack );
|
|
DEF_INST( purge_translation_lookaside_buffer );
|
|
DEF_INST( release_cms_lock );
|
|
DEF_INST( release_local_lock );
|
|
DEF_INST( set_clock );
|
|
DEF_INST( set_clock_comparator );
|
|
DEF_INST( set_cpu_timer );
|
|
DEF_INST( set_prefix );
|
|
DEF_INST( set_program_mask );
|
|
DEF_INST( set_psw_key_from_address );
|
|
DEF_INST( set_system_mask );
|
|
DEF_INST( shift_and_round_decimal );
|
|
DEF_INST( shift_left_double );
|
|
DEF_INST( shift_left_double_logical );
|
|
DEF_INST( shift_left_single );
|
|
DEF_INST( shift_left_single_logical );
|
|
DEF_INST( shift_right_double );
|
|
DEF_INST( shift_right_double_logical );
|
|
DEF_INST( shift_right_single );
|
|
DEF_INST( shift_right_single_logical );
|
|
DEF_INST( signal_processor );
|
|
DEF_INST( store );
|
|
DEF_INST( store_character );
|
|
DEF_INST( store_characters_under_mask );
|
|
DEF_INST( store_clock );
|
|
DEF_INST( store_clock_comparator );
|
|
DEF_INST( store_control );
|
|
DEF_INST( store_cpu_address );
|
|
DEF_INST( store_cpu_id );
|
|
DEF_INST( store_cpu_timer );
|
|
DEF_INST( store_halfword );
|
|
DEF_INST( store_multiple );
|
|
DEF_INST( store_prefix );
|
|
DEF_INST( store_then_and_system_mask );
|
|
DEF_INST( store_then_or_system_mask );
|
|
DEF_INST( store_using_real_address );
|
|
DEF_INST( subtract );
|
|
DEF_INST( subtract_decimal );
|
|
DEF_INST( subtract_halfword );
|
|
DEF_INST( subtract_logical );
|
|
DEF_INST( subtract_logical_register );
|
|
DEF_INST( subtract_register );
|
|
DEF_INST( supervisor_call );
|
|
DEF_INST( svc_assist );
|
|
DEF_INST( test_and_set );
|
|
DEF_INST( test_block );
|
|
DEF_INST( test_protection );
|
|
DEF_INST( test_under_mask );
|
|
DEF_INST( trace );
|
|
DEF_INST( trace_initial_srb_dispatch );
|
|
DEF_INST( trace_io_interruption );
|
|
DEF_INST( trace_program_interruption );
|
|
DEF_INST( trace_svc_interruption );
|
|
DEF_INST( trace_svc_return );
|
|
DEF_INST( trace_task_dispatch );
|
|
DEF_INST( translate );
|
|
DEF_INST( translate_and_test );
|
|
DEF_INST( unpack );
|
|
DEF_INST( update_tree );
|
|
DEF_INST( zero_and_add );
|
|
|
|
/*-------------------------------------------------------------------*/
|
|
/* Optimized Instructions */
|
|
/*-------------------------------------------------------------------*/
|
|
/* The following instructions have separate instruction functions */
|
|
/* defined for multiple variants of itself, such as the operand-2 */
|
|
/* register number of the Load/Add/Compare Register instruction or */
|
|
/* the condition code of a Branch on Condition instruction. Doing */
|
|
/* so allows the instruction's decoder and execution logic to use */
|
|
/* pre-known constant values resulting in much shorter and simpler */
|
|
/* code, thus allowing the C compiler to more efficiently optimize */
|
|
/* the code even further, resulting in a much faster intruction. */
|
|
/*-------------------------------------------------------------------*/
|
|
|
|
#ifdef OPTION_OPTINST
|
|
|
|
// Load Register
|
|
|
|
#define LRdefgen(r1, r2) \
|
|
DEF_INST(18 ## r1 ## r2)
|
|
|
|
#define LRdefgenr2(r1) \
|
|
LRdefgen(r1, 0); \
|
|
LRdefgen(r1, 1); \
|
|
LRdefgen(r1, 2); \
|
|
LRdefgen(r1, 3); \
|
|
LRdefgen(r1, 4); \
|
|
LRdefgen(r1, 5); \
|
|
LRdefgen(r1, 6); \
|
|
LRdefgen(r1, 7); \
|
|
LRdefgen(r1, 8); \
|
|
LRdefgen(r1, 9); \
|
|
LRdefgen(r1, A); \
|
|
LRdefgen(r1, B); \
|
|
LRdefgen(r1, C); \
|
|
LRdefgen(r1, D); \
|
|
LRdefgen(r1, E); \
|
|
LRdefgen(r1, F)
|
|
|
|
LRdefgenr2(0);
|
|
LRdefgenr2(1);
|
|
LRdefgenr2(2);
|
|
LRdefgenr2(3);
|
|
LRdefgenr2(4);
|
|
LRdefgenr2(5);
|
|
LRdefgenr2(6);
|
|
LRdefgenr2(7);
|
|
LRdefgenr2(8);
|
|
LRdefgenr2(9);
|
|
LRdefgenr2(A);
|
|
LRdefgenr2(B);
|
|
LRdefgenr2(C);
|
|
LRdefgenr2(D);
|
|
LRdefgenr2(E);
|
|
LRdefgenr2(F);
|
|
|
|
// Add Logical Register
|
|
|
|
#define ALRdefgen(r1, r2) \
|
|
DEF_INST(1E ## r1 ## r2)
|
|
|
|
#define ALRdefgenr2(r1) \
|
|
ALRdefgen(r1, 0); \
|
|
ALRdefgen(r1, 1); \
|
|
ALRdefgen(r1, 2); \
|
|
ALRdefgen(r1, 3); \
|
|
ALRdefgen(r1, 4); \
|
|
ALRdefgen(r1, 5); \
|
|
ALRdefgen(r1, 6); \
|
|
ALRdefgen(r1, 7); \
|
|
ALRdefgen(r1, 8); \
|
|
ALRdefgen(r1, 9); \
|
|
ALRdefgen(r1, A); \
|
|
ALRdefgen(r1, B); \
|
|
ALRdefgen(r1, C); \
|
|
ALRdefgen(r1, D); \
|
|
ALRdefgen(r1, E); \
|
|
ALRdefgen(r1, F)
|
|
|
|
ALRdefgenr2(0);
|
|
ALRdefgenr2(1);
|
|
ALRdefgenr2(2);
|
|
ALRdefgenr2(3);
|
|
ALRdefgenr2(4);
|
|
ALRdefgenr2(5);
|
|
ALRdefgenr2(6);
|
|
ALRdefgenr2(7);
|
|
ALRdefgenr2(8);
|
|
ALRdefgenr2(9);
|
|
ALRdefgenr2(A);
|
|
ALRdefgenr2(B);
|
|
ALRdefgenr2(C);
|
|
ALRdefgenr2(D);
|
|
ALRdefgenr2(E);
|
|
ALRdefgenr2(F);
|
|
|
|
// Compare Logical Register
|
|
|
|
#define CLRdefgen(r1, r2) \
|
|
DEF_INST(15 ## r1 ## r2)
|
|
|
|
#define CLRdefgenr2(r1) \
|
|
CLRdefgen(r1, 0); \
|
|
CLRdefgen(r1, 1); \
|
|
CLRdefgen(r1, 2); \
|
|
CLRdefgen(r1, 3); \
|
|
CLRdefgen(r1, 4); \
|
|
CLRdefgen(r1, 5); \
|
|
CLRdefgen(r1, 6); \
|
|
CLRdefgen(r1, 7); \
|
|
CLRdefgen(r1, 8); \
|
|
CLRdefgen(r1, 9); \
|
|
CLRdefgen(r1, A); \
|
|
CLRdefgen(r1, B); \
|
|
CLRdefgen(r1, C); \
|
|
CLRdefgen(r1, D); \
|
|
CLRdefgen(r1, E); \
|
|
CLRdefgen(r1, F)
|
|
|
|
CLRdefgenr2(0);
|
|
CLRdefgenr2(1);
|
|
CLRdefgenr2(2);
|
|
CLRdefgenr2(3);
|
|
CLRdefgenr2(4);
|
|
CLRdefgenr2(5);
|
|
CLRdefgenr2(6);
|
|
CLRdefgenr2(7);
|
|
CLRdefgenr2(8);
|
|
CLRdefgenr2(9);
|
|
CLRdefgenr2(A);
|
|
CLRdefgenr2(B);
|
|
CLRdefgenr2(C);
|
|
CLRdefgenr2(D);
|
|
CLRdefgenr2(E);
|
|
CLRdefgenr2(F);
|
|
|
|
// Load Address
|
|
|
|
DEF_INST(4100);
|
|
DEF_INST(4110);
|
|
DEF_INST(4120);
|
|
DEF_INST(4130);
|
|
DEF_INST(4140);
|
|
DEF_INST(4150);
|
|
DEF_INST(4160);
|
|
DEF_INST(4170);
|
|
DEF_INST(4180);
|
|
DEF_INST(4190);
|
|
DEF_INST(41A0);
|
|
DEF_INST(41B0);
|
|
DEF_INST(41C0);
|
|
DEF_INST(41D0);
|
|
DEF_INST(41E0);
|
|
DEF_INST(41F0);
|
|
|
|
// Branch on Condition
|
|
|
|
DEF_INST(47_0);
|
|
DEF_INST( nop4 );
|
|
DEF_INST(4710);
|
|
DEF_INST(4720);
|
|
DEF_INST(4730);
|
|
DEF_INST(4740);
|
|
DEF_INST(4750);
|
|
//F_INST(47_0); // (why?!)
|
|
DEF_INST(4770);
|
|
DEF_INST(4780);
|
|
//F_INST(47_0); // (why?!)
|
|
DEF_INST(47A0);
|
|
DEF_INST(47B0);
|
|
DEF_INST(47C0);
|
|
DEF_INST(47D0);
|
|
DEF_INST(47E0);
|
|
DEF_INST(47F0);
|
|
|
|
// Store
|
|
|
|
DEF_INST(5000);
|
|
DEF_INST(5010);
|
|
DEF_INST(5020);
|
|
DEF_INST(5030);
|
|
DEF_INST(5040);
|
|
DEF_INST(5050);
|
|
DEF_INST(5060);
|
|
DEF_INST(5070);
|
|
DEF_INST(5080);
|
|
DEF_INST(5090);
|
|
DEF_INST(50A0);
|
|
DEF_INST(50B0);
|
|
DEF_INST(50C0);
|
|
DEF_INST(50D0);
|
|
DEF_INST(50E0);
|
|
DEF_INST(50F0);
|
|
|
|
// Compare Logical
|
|
|
|
DEF_INST(5500);
|
|
DEF_INST(5510);
|
|
DEF_INST(5520);
|
|
DEF_INST(5530);
|
|
DEF_INST(5540);
|
|
DEF_INST(5550);
|
|
DEF_INST(5560);
|
|
DEF_INST(5570);
|
|
DEF_INST(5580);
|
|
DEF_INST(5590);
|
|
DEF_INST(55A0);
|
|
DEF_INST(55B0);
|
|
DEF_INST(55C0);
|
|
DEF_INST(55D0);
|
|
DEF_INST(55E0);
|
|
DEF_INST(55F0);
|
|
|
|
// Load
|
|
|
|
DEF_INST(5800);
|
|
DEF_INST(5810);
|
|
DEF_INST(5820);
|
|
DEF_INST(5830);
|
|
DEF_INST(5840);
|
|
DEF_INST(5850);
|
|
DEF_INST(5860);
|
|
DEF_INST(5870);
|
|
DEF_INST(5880);
|
|
DEF_INST(5890);
|
|
DEF_INST(58A0);
|
|
DEF_INST(58B0);
|
|
DEF_INST(58C0);
|
|
DEF_INST(58D0);
|
|
DEF_INST(58E0);
|
|
DEF_INST(58F0);
|
|
|
|
// Branch Relative on Condition
|
|
|
|
DEF_INST( A714 );
|
|
DEF_INST( A724 );
|
|
DEF_INST( A734 );
|
|
DEF_INST( A744 );
|
|
DEF_INST( A754 );
|
|
DEF_INST( A774 );
|
|
DEF_INST( A784 );
|
|
DEF_INST( A7A4 );
|
|
DEF_INST( A7B4 );
|
|
DEF_INST( A7C4 );
|
|
DEF_INST( A7D4 );
|
|
DEF_INST( A7E4 );
|
|
DEF_INST( A7F4 );
|
|
|
|
// Insert Characters Under Mask
|
|
|
|
DEF_INST( BF_7 );
|
|
DEF_INST( BF_F );
|
|
DEF_INST( BF_x );
|
|
|
|
// Test Under Mask
|
|
|
|
DEF_INST(9180);
|
|
DEF_INST(9140);
|
|
DEF_INST(9120);
|
|
DEF_INST(9110);
|
|
DEF_INST(9108);
|
|
DEF_INST(9104);
|
|
DEF_INST(9102);
|
|
DEF_INST(9101);
|
|
|
|
// Subtract Logical Register
|
|
|
|
#define SLRdefgen(r1, r2) \
|
|
DEF_INST(1F ## r1 ## r2)
|
|
|
|
#define SLRdefgenr2(r1) \
|
|
SLRdefgen(r1, 0); \
|
|
SLRdefgen(r1, 1); \
|
|
SLRdefgen(r1, 2); \
|
|
SLRdefgen(r1, 3); \
|
|
SLRdefgen(r1, 4); \
|
|
SLRdefgen(r1, 5); \
|
|
SLRdefgen(r1, 6); \
|
|
SLRdefgen(r1, 7); \
|
|
SLRdefgen(r1, 8); \
|
|
SLRdefgen(r1, 9); \
|
|
SLRdefgen(r1, A); \
|
|
SLRdefgen(r1, B); \
|
|
SLRdefgen(r1, C); \
|
|
SLRdefgen(r1, D); \
|
|
SLRdefgen(r1, E); \
|
|
SLRdefgen(r1, F)
|
|
|
|
SLRdefgenr2(0);
|
|
SLRdefgenr2(1);
|
|
SLRdefgenr2(2);
|
|
SLRdefgenr2(3);
|
|
SLRdefgenr2(4);
|
|
SLRdefgenr2(5);
|
|
SLRdefgenr2(6);
|
|
SLRdefgenr2(7);
|
|
SLRdefgenr2(8);
|
|
SLRdefgenr2(9);
|
|
SLRdefgenr2(A);
|
|
SLRdefgenr2(B);
|
|
SLRdefgenr2(C);
|
|
SLRdefgenr2(D);
|
|
SLRdefgenr2(E);
|
|
SLRdefgenr2(F);
|
|
|
|
#if !defined( OPTION_NO_E3_OPTINST )
|
|
|
|
// Load/Store 64-bit
|
|
|
|
DEF_INST( E3_0 );
|
|
DEF_INST( E3_0______04 );
|
|
DEF_INST( E3_0______24 );
|
|
|
|
#endif
|
|
|
|
#endif /* OPTION_OPTINST */
|
|
|
|
/* end of OPCODE.H */
|