1 #include <stdio.h> 2 #include "opcodes.h" 3 4 /* The FLOGR insn reads from register R2 and writes to register R1 and 5 R1 + 1. So we need to distinguish three cases: 6 7 (1) All three registers R1, R1 + 1, and R2 are distinct 8 (2) R2 == R1 9 (3) R2 == R1 + 1 10 11 These are tested by flogr1, flogr2, and flogr3, respectively. */ 12 13 /* Call FLOGR on INPUT. The results are returned through the parms. */ 14 15 /* R2 != R1 && R2 != R1 + 1 */ 16 void 17 flogr1(unsigned long input, unsigned long *bitpos, unsigned long *modval, 18 unsigned int *cc) 19 { 20 unsigned int psw; 21 register unsigned long value asm("4") = input; 22 23 asm volatile ( FLOGR(2,4) 24 "ipm %[psw]\n\t" 25 "stg 2, %[bitpos]\n\t" 26 "stg 3, %[modval]\n\t" 27 : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval), 28 [psw]"=&d"(psw) 29 : [val] "d"(value) 30 : "2", "3", "cc"); 31 32 *cc = psw >> 28; 33 #if 0 34 printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n", 35 value, *bitpos, *modval, *cc); 36 #endif 37 } 38 39 /* R2 == R1 */ 40 void 41 flogr2(unsigned long input, unsigned long *bitpos, unsigned long *modval, 42 unsigned int *cc) 43 { 44 unsigned int psw; 45 register unsigned long value asm("2") = input; 46 47 asm volatile ( FLOGR(2,2) 48 "ipm %[psw]\n\t" 49 "stg 2, %[bitpos]\n\t" 50 "stg 3, %[modval]\n\t" 51 : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval), 52 [psw]"=&d"(psw), [val] "+d"(value) 53 : 54 : "3", "cc"); 55 56 *cc = psw >> 28; 57 #if 0 58 printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n", 59 value, *bitpos, *modval, *cc); 60 #endif 61 } 62 63 /* R2 == R1 + 1 */ 64 void 65 flogr3(unsigned long input, unsigned long *bitpos, unsigned long *modval, 66 unsigned int *cc) 67 { 68 unsigned int psw; 69 register unsigned long value asm("3") = input; 70 71 asm volatile ( FLOGR(2,3) 72 "ipm %[psw]\n\t" 73 "stg 2, %[bitpos]\n\t" 74 "stg 3, %[modval]\n\t" 75 : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval), 76 [psw]"=&d"(psw), [val] "+d"(value) 77 : 78 : "2", "cc"); 79 80 *cc = psw >> 28; 81 #if 0 82 printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n", 83 value, *bitpos, *modval, *cc); 84 #endif 85 } 86 87 void 88 runtest(void (*func)(unsigned long, unsigned long *, unsigned long *, 89 unsigned int *)) 90 { 91 unsigned long bitpos, modval, value; 92 unsigned int cc; 93 int i; 94 95 /* Value 0 is special */ 96 value = 0; 97 func(value, &bitpos, &modval, &cc); 98 if (modval != 0) fprintf(stderr, "modval is wrong for %lx\n", value); 99 if (bitpos != 64) fprintf(stderr, "bitpos is wrong for %lx\n", value); 100 if (cc != 0) fprintf(stderr, "cc is wrong for %lx\n", value); 101 102 /* Test with exactly 1 bit set */ 103 for (i = 0; i < 64; ++i) { 104 value = 1ull << i; 105 func(value, &bitpos, &modval, &cc); 106 if (modval != 0) fprintf(stderr, "modval is wrong for %lx\n", value); 107 if (bitpos != 63 - i) fprintf(stderr, "bitpos is wrong for %lx\n", value); 108 if (cc != 2) fprintf(stderr, "cc is wrong for %lx\n", value); 109 } 110 111 /* Test with all bits 1 right from first 1 bit */ 112 for (i = 1; i < 64; ++i) { 113 value = 1ull << i; 114 value = value | (value - 1); 115 func(value, &bitpos, &modval, &cc); 116 if (modval != (value >> 1)) fprintf(stderr, "modval is wrong for %lx\n", value); 117 if (bitpos != 63 - i) fprintf(stderr, "bitpos is wrong for %lx\n", value); 118 if (cc != 2) fprintf(stderr, "cc is wrong for %lx\n", value); 119 } 120 } 121 122 123 int main() 124 { 125 runtest(flogr1); 126 runtest(flogr2); 127 runtest(flogr3); 128 129 return 0; 130 } 131