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 SUB_REG_MEM(insn, s1, s2, NOBORROW)		\
      7 ({							\
      8 	unsigned long tmp = s1;				\
      9 	int cc;						\
     10 	asm volatile(	"lghi 0," #NOBORROW "\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 " %16.16lX - %16.16lX - %d = %16.16lX (cc=%d)\n", s1, s2, !NOBORROW, tmp, cc); \
     19 })
     20 
     21 #define SUB_REG_REG(insn, s1, s2, NOBORROW)		\
     22 ({							\
     23 	unsigned long tmp = s1;				\
     24 	int cc;						\
     25 	asm volatile(	"lghi 0," #NOBORROW "\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 " %16.16lX - %16.16lX - %d = %16.16lX (cc=%d)\n", s1, s2, !NOBORROW, tmp, cc); \
     34 })
     35 
     36 #define SUB_REG_IMM(insn, s1, s2, NOBORROW)		\
     37 ({							\
     38 	register unsigned long tmp asm("2") = s1;	\
     39 	int cc;						\
     40 	asm volatile(	"lghi 0," #NOBORROW "\n"		\
     41 			"aghi 0, 0\n"			\
     42                         insn(2,s2)			\
     43 			"ipm %1\n"			\
     44 			"srl %1,28\n"			\
     45 			: "+d" (tmp), "=d" (cc)		\
     46 			: "d" (tmp)			\
     47 			: "0", "cc");			\
     48 	v = tmp;					\
     49 	printf(#insn " %16.16lX - %16.16lX - %d = %16.16lX (cc=%d)\n", s1, (unsigned long) 0x00000000##s2, !NOBORROW, v, cc); \
     50 })
     51 
     52 #define memsweep(i, s2, carryset)				\
     53 ({								\
     54 	SUB_REG_MEM(i, 0ul, s2, carryset);			\
     55 	SUB_REG_MEM(i, 1ul, s2, carryset);			\
     56 	SUB_REG_MEM(i, 0xfffful, s2, carryset);			\
     57 	SUB_REG_MEM(i, 0x7ffful, s2, carryset);			\
     58 	SUB_REG_MEM(i, 0x8000ul, s2, carryset);			\
     59 	SUB_REG_MEM(i, 0xfffffffful, s2, carryset);		\
     60 	SUB_REG_MEM(i, 0x80000000ul, s2, carryset);		\
     61 	SUB_REG_MEM(i, 0x7ffffffful, s2, carryset);		\
     62 	SUB_REG_MEM(i, 0xfffffffffffffffful, s2, carryset);	\
     63 	SUB_REG_MEM(i, 0x8000000000000000ul, s2, carryset);	\
     64 	SUB_REG_MEM(i, 0x7ffffffffffffffful, s2, carryset);	\
     65 })
     66 
     67 #define regsweep(i, s2, carryset)				\
     68 ({								\
     69 	SUB_REG_REG(i, 0ul, s2, carryset);			\
     70 	SUB_REG_REG(i, 1ul, s2, carryset);			\
     71 	SUB_REG_REG(i, 0xfffful, s2, carryset);			\
     72 	SUB_REG_REG(i, 0x7ffful, s2, carryset);			\
     73 	SUB_REG_REG(i, 0x8000ul, s2, carryset);			\
     74 	SUB_REG_REG(i, 0xfffffffful, s2, carryset);		\
     75 	SUB_REG_REG(i, 0x80000000ul, s2, carryset);		\
     76 	SUB_REG_REG(i, 0x7ffffffful, s2, carryset);		\
     77 	SUB_REG_REG(i, 0xfffffffffffffffful, s2, carryset);	\
     78 	SUB_REG_REG(i, 0x8000000000000000ul, s2, carryset);	\
     79 	SUB_REG_REG(i, 0x7ffffffffffffffful, s2, carryset);	\
     80 })
     81 
     82 #define immsweep(i, s2, carryset)				\
     83 ({								\
     84 	SUB_REG_IMM(i, 0ul, s2, carryset);			\
     85 	SUB_REG_IMM(i, 1ul, s2, carryset);			\
     86 	SUB_REG_IMM(i, 0xfffful, s2, carryset);			\
     87 	SUB_REG_IMM(i, 0x7ffful, s2, carryset);			\
     88 	SUB_REG_IMM(i, 0x8000ul, s2, carryset);			\
     89 	SUB_REG_IMM(i, 0xfffffffful, s2, carryset);		\
     90 	SUB_REG_IMM(i, 0x80000000ul, s2, carryset);		\
     91 	SUB_REG_IMM(i, 0x7ffffffful, s2, carryset);		\
     92 	SUB_REG_IMM(i, 0xfffffffffffffffful, s2, carryset);	\
     93 	SUB_REG_IMM(i, 0x8000000000000000ul, s2, carryset);	\
     94 	SUB_REG_IMM(i, 0x7ffffffffffffffful, s2, carryset);	\
     95 })
     96 
     97 #define SUB_REG_LDISP(insn, s1, s2, NOBORROW)			\
     98 ({								\
     99 	register unsigned long tmp asm("2") = s1;		\
    100 	register unsigned long *addr asm("5") = &s2;		\
    101 	int cc;							\
    102 	asm volatile(	"lghi 0," #NOBORROW "\n"		\
    103 			"aghi 0, 0\n"				\
    104 			insn(2,0,5,000,00)			\
    105 			"ipm %1\n"				\
    106 			"srl %1,28\n"				\
    107 			: "+d" (tmp), "=d" (cc)			\
    108 			: "d" (tmp), "Q" (s2), "d"(addr)	\
    109 			: "cc");				\
    110 	v = tmp; /* work around GCC code gen bug */     \
    111 	printf(#insn " %16.16lX - %16.16lX - %d = %16.16lX (cc=%d)\n", s1, s2, !NOBORROW, v, cc); \
    112 })
    113 
    114 #define ldispsweep(i, s2, carryset)				\
    115 ({								\
    116 	SUB_REG_LDISP(i, 0ul, s2, carryset);			\
    117 	SUB_REG_LDISP(i, 1ul, s2, carryset);			\
    118 	SUB_REG_LDISP(i, 0xfffful, s2, carryset);		\
    119 	SUB_REG_LDISP(i, 0x7ffful, s2, carryset);		\
    120 	SUB_REG_LDISP(i, 0x8000ul, s2, carryset);		\
    121 	SUB_REG_LDISP(i, 0xfffffffful, s2, carryset);		\
    122 	SUB_REG_LDISP(i, 0x80000000ul, s2, carryset);		\
    123 	SUB_REG_LDISP(i, 0x7ffffffful, s2, carryset);		\
    124 	SUB_REG_LDISP(i, 0xfffffffffffffffful, s2, carryset);	\
    125 	SUB_REG_LDISP(i, 0x8000000000000000ul, s2, carryset);	\
    126 	SUB_REG_LDISP(i, 0x7ffffffffffffffful, s2, carryset);	\
    127 })
    128