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