1b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#include <stdio.h> 2d50650d6cb0e3577ba28b470a4e5f5df8368afaasewardj#include "opcodes.h" 3b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 48ef7224ba09b9320f1417cabbd56109e0408351esewardj/* The FLOGR insn reads from register R2 and writes to register R1 and 58ef7224ba09b9320f1417cabbd56109e0408351esewardj R1 + 1. So we need to distinguish three cases: 68ef7224ba09b9320f1417cabbd56109e0408351esewardj 78ef7224ba09b9320f1417cabbd56109e0408351esewardj (1) All three registers R1, R1 + 1, and R2 are distinct 88ef7224ba09b9320f1417cabbd56109e0408351esewardj (2) R2 == R1 98ef7224ba09b9320f1417cabbd56109e0408351esewardj (3) R2 == R1 + 1 108ef7224ba09b9320f1417cabbd56109e0408351esewardj 118ef7224ba09b9320f1417cabbd56109e0408351esewardj These are tested by flogr1, flogr2, and flogr3, respectively. */ 12b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 13b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj/* Call FLOGR on INPUT. The results are returned through the parms. */ 148ef7224ba09b9320f1417cabbd56109e0408351esewardj 158ef7224ba09b9320f1417cabbd56109e0408351esewardj/* R2 != R1 && R2 != R1 + 1 */ 16b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardjvoid 178ef7224ba09b9320f1417cabbd56109e0408351esewardjflogr1(unsigned long input, unsigned long *bitpos, unsigned long *modval, 188ef7224ba09b9320f1417cabbd56109e0408351esewardj unsigned int *cc) 19b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj{ 20b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj unsigned int psw; 21b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj register unsigned long value asm("4") = input; 22b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 23d50650d6cb0e3577ba28b470a4e5f5df8368afaasewardj asm volatile ( FLOGR(2,4) 24b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj "ipm %[psw]\n\t" 25b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj "stg 2, %[bitpos]\n\t" 26b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj "stg 3, %[modval]\n\t" 27b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval), 28465adfd4c7776a768a7919e6119d0c144ae1aaeeflorian [psw]"=&d"(psw) 29b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj : [val] "d"(value) 30b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj : "2", "3", "cc"); 31b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 32b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj *cc = psw >> 28; 33b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#if 0 34b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n", 35b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj value, *bitpos, *modval, *cc); 36b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#endif 37b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj} 38b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 398ef7224ba09b9320f1417cabbd56109e0408351esewardj/* R2 == R1 */ 408ef7224ba09b9320f1417cabbd56109e0408351esewardjvoid 418ef7224ba09b9320f1417cabbd56109e0408351esewardjflogr2(unsigned long input, unsigned long *bitpos, unsigned long *modval, 428ef7224ba09b9320f1417cabbd56109e0408351esewardj unsigned int *cc) 438ef7224ba09b9320f1417cabbd56109e0408351esewardj{ 448ef7224ba09b9320f1417cabbd56109e0408351esewardj unsigned int psw; 458ef7224ba09b9320f1417cabbd56109e0408351esewardj register unsigned long value asm("2") = input; 468ef7224ba09b9320f1417cabbd56109e0408351esewardj 47d50650d6cb0e3577ba28b470a4e5f5df8368afaasewardj asm volatile ( FLOGR(2,2) 488ef7224ba09b9320f1417cabbd56109e0408351esewardj "ipm %[psw]\n\t" 498ef7224ba09b9320f1417cabbd56109e0408351esewardj "stg 2, %[bitpos]\n\t" 508ef7224ba09b9320f1417cabbd56109e0408351esewardj "stg 3, %[modval]\n\t" 518ef7224ba09b9320f1417cabbd56109e0408351esewardj : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval), 52465adfd4c7776a768a7919e6119d0c144ae1aaeeflorian [psw]"=&d"(psw), [val] "+d"(value) 538ef7224ba09b9320f1417cabbd56109e0408351esewardj : 548ef7224ba09b9320f1417cabbd56109e0408351esewardj : "3", "cc"); 558ef7224ba09b9320f1417cabbd56109e0408351esewardj 568ef7224ba09b9320f1417cabbd56109e0408351esewardj *cc = psw >> 28; 578ef7224ba09b9320f1417cabbd56109e0408351esewardj#if 0 588ef7224ba09b9320f1417cabbd56109e0408351esewardj printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n", 598ef7224ba09b9320f1417cabbd56109e0408351esewardj value, *bitpos, *modval, *cc); 608ef7224ba09b9320f1417cabbd56109e0408351esewardj#endif 618ef7224ba09b9320f1417cabbd56109e0408351esewardj} 628ef7224ba09b9320f1417cabbd56109e0408351esewardj 638ef7224ba09b9320f1417cabbd56109e0408351esewardj/* R2 == R1 + 1 */ 648ef7224ba09b9320f1417cabbd56109e0408351esewardjvoid 658ef7224ba09b9320f1417cabbd56109e0408351esewardjflogr3(unsigned long input, unsigned long *bitpos, unsigned long *modval, 668ef7224ba09b9320f1417cabbd56109e0408351esewardj unsigned int *cc) 678ef7224ba09b9320f1417cabbd56109e0408351esewardj{ 688ef7224ba09b9320f1417cabbd56109e0408351esewardj unsigned int psw; 698ef7224ba09b9320f1417cabbd56109e0408351esewardj register unsigned long value asm("3") = input; 708ef7224ba09b9320f1417cabbd56109e0408351esewardj 71d50650d6cb0e3577ba28b470a4e5f5df8368afaasewardj asm volatile ( FLOGR(2,3) 728ef7224ba09b9320f1417cabbd56109e0408351esewardj "ipm %[psw]\n\t" 738ef7224ba09b9320f1417cabbd56109e0408351esewardj "stg 2, %[bitpos]\n\t" 748ef7224ba09b9320f1417cabbd56109e0408351esewardj "stg 3, %[modval]\n\t" 758ef7224ba09b9320f1417cabbd56109e0408351esewardj : [bitpos]"=m"(*bitpos), [modval]"=m"(*modval), 76465adfd4c7776a768a7919e6119d0c144ae1aaeeflorian [psw]"=&d"(psw), [val] "+d"(value) 778ef7224ba09b9320f1417cabbd56109e0408351esewardj : 788ef7224ba09b9320f1417cabbd56109e0408351esewardj : "2", "cc"); 798ef7224ba09b9320f1417cabbd56109e0408351esewardj 808ef7224ba09b9320f1417cabbd56109e0408351esewardj *cc = psw >> 28; 818ef7224ba09b9320f1417cabbd56109e0408351esewardj#if 0 828ef7224ba09b9320f1417cabbd56109e0408351esewardj printf("value = %lx, bitpos = %lu, modval = %lx, cc = %d\n", 838ef7224ba09b9320f1417cabbd56109e0408351esewardj value, *bitpos, *modval, *cc); 848ef7224ba09b9320f1417cabbd56109e0408351esewardj#endif 858ef7224ba09b9320f1417cabbd56109e0408351esewardj} 868ef7224ba09b9320f1417cabbd56109e0408351esewardj 87b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardjvoid 888ef7224ba09b9320f1417cabbd56109e0408351esewardjruntest(void (*func)(unsigned long, unsigned long *, unsigned long *, 898ef7224ba09b9320f1417cabbd56109e0408351esewardj unsigned int *)) 90b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj{ 91b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj unsigned long bitpos, modval, value; 92b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj unsigned int cc; 93b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj int i; 94b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 95b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Value 0 is special */ 96b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj value = 0; 978ef7224ba09b9320f1417cabbd56109e0408351esewardj func(value, &bitpos, &modval, &cc); 98b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (modval != 0) fprintf(stderr, "modval is wrong for %lx\n", value); 99b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (bitpos != 64) fprintf(stderr, "bitpos is wrong for %lx\n", value); 100b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (cc != 0) fprintf(stderr, "cc is wrong for %lx\n", value); 101b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 102b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Test with exactly 1 bit set */ 103b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj for (i = 0; i < 64; ++i) { 104b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj value = 1ull << i; 1058ef7224ba09b9320f1417cabbd56109e0408351esewardj func(value, &bitpos, &modval, &cc); 106b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (modval != 0) fprintf(stderr, "modval is wrong for %lx\n", value); 107b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (bitpos != 63 - i) fprintf(stderr, "bitpos is wrong for %lx\n", value); 108b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (cc != 2) fprintf(stderr, "cc is wrong for %lx\n", value); 109b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 110b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 111b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Test with all bits 1 right from first 1 bit */ 112b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj for (i = 1; i < 64; ++i) { 113b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj value = 1ull << i; 114b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj value = value | (value - 1); 1158ef7224ba09b9320f1417cabbd56109e0408351esewardj func(value, &bitpos, &modval, &cc); 116b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (modval != (value >> 1)) fprintf(stderr, "modval is wrong for %lx\n", value); 117b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (bitpos != 63 - i) fprintf(stderr, "bitpos is wrong for %lx\n", value); 118b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj if (cc != 2) fprintf(stderr, "cc is wrong for %lx\n", value); 119b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj } 120b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj} 121b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 122b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 123b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardjint main() 124b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj{ 1258ef7224ba09b9320f1417cabbd56109e0408351esewardj runtest(flogr1); 1268ef7224ba09b9320f1417cabbd56109e0408351esewardj runtest(flogr2); 1278ef7224ba09b9320f1417cabbd56109e0408351esewardj runtest(flogr3); 128b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 129b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj return 0; 130b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj} 131