blob: 72f1d5ae1b6f2411b094b47d75c906c0b22ba924 [file] [log] [blame]
sewardjb5b87402011-03-07 16:05:35 +00001#include <stdio.h>
sewardjd50650d2011-04-13 14:57:44 +00002#include "opcodes.h"
sewardjb5b87402011-03-07 16:05:35 +00003
sewardj8ef72242011-03-24 08:58:42 +00004/* 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. */
sewardjb5b87402011-03-07 16:05:35 +000012
13/* Call FLOGR on INPUT. The results are returned through the parms. */
sewardj8ef72242011-03-24 08:58:42 +000014
15/* R2 != R1 && R2 != R1 + 1 */
sewardjb5b87402011-03-07 16:05:35 +000016void
sewardj8ef72242011-03-24 08:58:42 +000017flogr1(unsigned long input, unsigned long *bitpos, unsigned long *modval,
18 unsigned int *cc)
sewardjb5b87402011-03-07 16:05:35 +000019{
20 unsigned int psw;
21 register unsigned long value asm("4") = input;
22
sewardjd50650d2011-04-13 14:57:44 +000023 asm volatile ( FLOGR(2,4)
sewardjb5b87402011-03-07 16:05:35 +000024 "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
sewardj8ef72242011-03-24 08:58:42 +000039/* R2 == R1 */
sewardjb5b87402011-03-07 16:05:35 +000040void
sewardj8ef72242011-03-24 08:58:42 +000041flogr2(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
sewardjd50650d2011-04-13 14:57:44 +000047 asm volatile ( FLOGR(2,2)
sewardj8ef72242011-03-24 08:58:42 +000048 "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 */
64void
65flogr3(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
sewardjd50650d2011-04-13 14:57:44 +000071 asm volatile ( FLOGR(2,3)
sewardj8ef72242011-03-24 08:58:42 +000072 "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
87void
88runtest(void (*func)(unsigned long, unsigned long *, unsigned long *,
89 unsigned int *))
sewardjb5b87402011-03-07 16:05:35 +000090{
91 unsigned long bitpos, modval, value;
92 unsigned int cc;
93 int i;
94
95 /* Value 0 is special */
96 value = 0;
sewardj8ef72242011-03-24 08:58:42 +000097 func(value, &bitpos, &modval, &cc);
sewardjb5b87402011-03-07 16:05:35 +000098 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;
sewardj8ef72242011-03-24 08:58:42 +0000105 func(value, &bitpos, &modval, &cc);
sewardjb5b87402011-03-07 16:05:35 +0000106 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);
sewardj8ef72242011-03-24 08:58:42 +0000115 func(value, &bitpos, &modval, &cc);
sewardjb5b87402011-03-07 16:05:35 +0000116 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
123int main()
124{
sewardj8ef72242011-03-24 08:58:42 +0000125 runtest(flogr1);
126 runtest(flogr2);
127 runtest(flogr3);
sewardjb5b87402011-03-07 16:05:35 +0000128
129 return 0;
130}