Home | History | Annotate | Download | only in s390x
      1 #include <stdio.h>
      2 
      3 /* Dummy variable. Needed to work around GCC code generation bugs */
      4 volatile long v;
      5 
      6 #define ADD_REG_MEM(insn, s1, s2, CARRY)		\
      7 ({							\
      8 	unsigned long tmp = s1;				\
      9 	int cc;						\
     10 	asm volatile(	"lghi 0," #CARRY "\n"		\
     11 			"aghi 0, 0\n"			\
     12 			#insn " %0, %3\n"		\
     13 			"ipm %1\n"			\
     14 			"srl %1,28\n"			\
     15 			: "+d" (tmp), "=d" (cc)		\
     16 			: "d" (tmp), "Q" (s2)		\
     17 			: "0", "cc");			\
     18 	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, s2, tmp, cc); \
     19 })
     20 
     21 #define ADD_REG_REG(insn, s1, s2, CARRY)		\
     22 ({							\
     23 	unsigned long tmp = s1;				\
     24 	int cc;						\
     25 	asm volatile(	"lghi 0," #CARRY "\n"		\
     26 			"aghi 0, 0\n"			\
     27 			#insn " %0, %3\n"		\
     28 			"ipm %1\n"			\
     29 			"srl %1,28\n"			\
     30 			: "+d" (tmp), "=d" (cc)		\
     31 			: "d" (tmp), "d" (s2)		\
     32 			: "0", "cc");			\
     33 	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, s2, tmp, cc); \
     34 })
     35 
     36 #define ADD_REG_IMM(insn, s1, s2, CARRY)		\
     37 ({							\
     38 	unsigned long tmp = s1;				\
     39 	int cc;						\
     40 	asm volatile(	"lghi 0," #CARRY "\n"		\
     41 			"aghi 0, 0\n"			\
     42 			#insn " %0," #s2 "\n"		\
     43 			"ipm %1\n"			\
     44 			"srl %1,28\n"			\
     45 			: "+d" (tmp), "=d" (cc)		\
     46 			: "d" (tmp)			\
     47 			: "0", "cc");			\
     48 	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, (unsigned long) s2, tmp, cc); \
     49 })
     50 
     51 #define ADD_MEM_IMM(insn, s1, s2, CARRY)		\
     52 ({							\
     53 	unsigned long tmp = s1, v2;			\
     54 	register unsigned long *addr asm("5") = &tmp;	\
     55 	int cc;						\
     56 	asm volatile(	"lghi 0," #CARRY "\n"		\
     57 			"aghi 0, 0\n"			\
     58 			insn(s2,5,000,00)		\
     59 			"ipm %1\n"			\
     60 			"srl %1,28\n"			\
     61 			: "+Q" (tmp), "=d" (cc)		\
     62 			: "Q" (tmp), "d" (addr)		\
     63 			: "0", "cc");			\
     64         v2 =  (((signed long)((unsigned long)0x##s2 << 56)) >> 56); \
     65 	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, v2, tmp, cc); \
     66 })
     67 
     68 
     69 #define memsweep(i, s2, carryset)				\
     70 ({								\
     71 	ADD_REG_MEM(i, 0ul, s2, carryset);			\
     72 	ADD_REG_MEM(i, 1ul, s2, carryset);			\
     73 	ADD_REG_MEM(i, 0xfffful, s2, carryset);			\
     74 	ADD_REG_MEM(i, 0x7ffful, s2, carryset);			\
     75 	ADD_REG_MEM(i, 0x8000ul, s2, carryset);			\
     76 	ADD_REG_MEM(i, 0xfffffffful, s2, carryset);		\
     77 	ADD_REG_MEM(i, 0x80000000ul, s2, carryset);		\
     78 	ADD_REG_MEM(i, 0x7ffffffful, s2, carryset);		\
     79 	ADD_REG_MEM(i, 0xfffffffffffffffful, s2, carryset);	\
     80 	ADD_REG_MEM(i, 0x8000000000000000ul, s2, carryset);	\
     81 	ADD_REG_MEM(i, 0x7ffffffffffffffful, s2, carryset);	\
     82 })
     83 
     84 #define regsweep(i, s2, carryset)				\
     85 ({								\
     86 	ADD_REG_REG(i, 0ul, s2, carryset);			\
     87 	ADD_REG_REG(i, 1ul, s2, carryset);			\
     88 	ADD_REG_REG(i, 0xfffful, s2, carryset);			\
     89 	ADD_REG_REG(i, 0x7ffful, s2, carryset);			\
     90 	ADD_REG_REG(i, 0x8000ul, s2, carryset);			\
     91 	ADD_REG_REG(i, 0xfffffffful, s2, carryset);		\
     92 	ADD_REG_REG(i, 0x80000000ul, s2, carryset);		\
     93 	ADD_REG_REG(i, 0x7ffffffful, s2, carryset);		\
     94 	ADD_REG_REG(i, 0xfffffffffffffffful, s2, carryset);	\
     95 	ADD_REG_REG(i, 0x8000000000000000ul, s2, carryset);	\
     96 	ADD_REG_REG(i, 0x7ffffffffffffffful, s2, carryset);	\
     97 })
     98 
     99 #define immsweep(i, s2, carryset)				\
    100 ({								\
    101 	ADD_REG_IMM(i, 0ul, s2, carryset);			\
    102 	ADD_REG_IMM(i, 1ul, s2, carryset);			\
    103 	ADD_REG_IMM(i, 0xfffful, s2, carryset);			\
    104 	ADD_REG_IMM(i, 0x7ffful, s2, carryset);			\
    105 	ADD_REG_IMM(i, 0x8000ul, s2, carryset);			\
    106 	ADD_REG_IMM(i, 0xfffffffful, s2, carryset);		\
    107 	ADD_REG_IMM(i, 0x80000000ul, s2, carryset);		\
    108 	ADD_REG_IMM(i, 0x7ffffffful, s2, carryset);		\
    109 	ADD_REG_IMM(i, 0xfffffffffffffffful, s2, carryset);	\
    110 	ADD_REG_IMM(i, 0x8000000000000000ul, s2, carryset);	\
    111 	ADD_REG_IMM(i, 0x7ffffffffffffffful, s2, carryset);	\
    112 })
    113 
    114 #define memimmsweep(i, s2, carryset)				\
    115 ({								\
    116 	ADD_MEM_IMM(i, 0ul, s2, carryset);			\
    117 	ADD_MEM_IMM(i, 1ul, s2, carryset);			\
    118 	ADD_MEM_IMM(i, 0xfffful, s2, carryset);			\
    119 	ADD_MEM_IMM(i, 0x7ffful, s2, carryset);			\
    120 	ADD_MEM_IMM(i, 0x8000ul, s2, carryset);			\
    121 	ADD_MEM_IMM(i, 0xfffffffful, s2, carryset);		\
    122 	ADD_MEM_IMM(i, 0x80000000ul, s2, carryset);		\
    123 	ADD_MEM_IMM(i, 0x7ffffffful, s2, carryset);		\
    124 	ADD_MEM_IMM(i, 0xfffffffffffffffful, s2, carryset);	\
    125 	ADD_MEM_IMM(i, 0x8000000000000000ul, s2, carryset);	\
    126 	ADD_MEM_IMM(i, 0x7ffffffffffffffful, s2, carryset);	\
    127 })
    128 
    129 #define ahysweep(i, s2, carryset)				\
    130 ({								\
    131 	ADD_REG_MEM(i, 0ul, s2, carryset);			\
    132 	ADD_REG_MEM(i, 1ul, s2, carryset);			\
    133 	ADD_REG_MEM(i, 0xfffful, s2, carryset);			\
    134 	ADD_REG_MEM(i, 0x7ffful, s2, carryset);			\
    135 	ADD_REG_MEM(i, 0x8000ul, s2, carryset);			\
    136 	ADD_REG_MEM(i, 0xfffffffful, s2, carryset);		\
    137 	ADD_REG_MEM(i, 0x80000000ul, s2, carryset);		\
    138 	ADD_REG_MEM(i, 0x7ffffffful, s2, carryset);		\
    139 	ADD_REG_MEM(i, 0xfffffffffffffffful, s2, carryset);	\
    140 	ADD_REG_MEM(i, 0x8000000000000000ul, s2, carryset);	\
    141 	ADD_REG_MEM(i, 0x7ffffffffffffffful, s2, carryset);	\
    142 })
    143 
    144 #define ADD_REG_LDISP(insn, s1, s2, CARRY)			\
    145 ({								\
    146 	register unsigned long tmp asm("2") = s1;		\
    147 	register unsigned long *addr asm("5") = &s2;		\
    148 	int cc;							\
    149 	asm volatile(	"lghi 0," #CARRY "\n"			\
    150 			"aghi 0, 0\n"				\
    151 			insn(2,0,5,000,00)			\
    152 			"ipm %1\n"				\
    153 			"srl %1,28\n"				\
    154 			: "+d" (tmp), "=d" (cc)			\
    155 			: "d" (tmp), "Q" (s2), "d"(addr)	\
    156 			: "cc");				\
    157 	v = tmp; /* work around GCC code gen bug */     \
    158 	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, s2, v, cc); \
    159 })
    160 
    161 #define ldispsweep(i, s2, carryset)				\
    162 ({								\
    163 	ADD_REG_LDISP(i, 0ul, s2, carryset);			\
    164 	ADD_REG_LDISP(i, 1ul, s2, carryset);			\
    165 	ADD_REG_LDISP(i, 0xfffful, s2, carryset);		\
    166 	ADD_REG_LDISP(i, 0x7ffful, s2, carryset);		\
    167 	ADD_REG_LDISP(i, 0x8000ul, s2, carryset);		\
    168 	ADD_REG_LDISP(i, 0xfffffffful, s2, carryset);		\
    169 	ADD_REG_LDISP(i, 0x80000000ul, s2, carryset);		\
    170 	ADD_REG_LDISP(i, 0x7ffffffful, s2, carryset);		\
    171 	ADD_REG_LDISP(i, 0xfffffffffffffffful, s2, carryset);	\
    172 	ADD_REG_LDISP(i, 0x8000000000000000ul, s2, carryset);	\
    173 	ADD_REG_LDISP(i, 0x7ffffffffffffffful, s2, carryset);	\
    174 })
    175 
    176 #define ADD_REG_XIMM(insn, s1, us2,s2, CARRY)		\
    177 ({							\
    178 	register unsigned long tmp asm("2") = s1;	\
    179 	int cc;						\
    180 	asm volatile(	"lghi 0," #CARRY "\n"		\
    181 			"aghi 0, 0\n"			\
    182 			insn(2,s2)			\
    183 			"ipm %1\n"			\
    184 			"srl %1,28\n"			\
    185 			: "+d" (tmp), "=d" (cc)		\
    186 			: "d" (tmp)			\
    187 			: "0", "cc");			\
    188 	v = tmp; /* work around GCC code gen bug */     \
    189 	printf(#insn " " #CARRY " + %16.16lX + %16.16lX = %16.16lX (cc=%d)\n", s1, (unsigned long) 0x##us2##s2, v, cc); \
    190 })
    191 
    192 #define ximmsweep(i, us2, s2, carryset)					\
    193 ({									\
    194 	ADD_REG_XIMM(i, 0ul, us2, s2, carryset);			\
    195 	ADD_REG_XIMM(i, 1ul, us2, s2, carryset);			\
    196 	ADD_REG_XIMM(i, 0xfffful, us2, s2, carryset);			\
    197 	ADD_REG_XIMM(i, 0x7ffful, us2, s2, carryset);			\
    198 	ADD_REG_XIMM(i, 0x8000ul, us2, s2, carryset);			\
    199 	ADD_REG_XIMM(i, 0xfffffffful, us2, s2, carryset);		\
    200 	ADD_REG_XIMM(i, 0x80000000ul, us2, s2, carryset);		\
    201 	ADD_REG_XIMM(i, 0x7ffffffful, us2, s2, carryset);		\
    202 	ADD_REG_XIMM(i, 0xfffffffffffffffful, us2, s2, carryset);	\
    203 	ADD_REG_XIMM(i, 0x8000000000000000ul, us2, s2, carryset);	\
    204 	ADD_REG_XIMM(i, 0x7ffffffffffffffful, us2, s2, carryset);	\
    205 })
    206 
    207