1
2
3
4
5 package rewriteppc64
6
7 import (
8 "math/bits"
9
10 "cmd/compile/internal/ssa"
11 )
12
13 func getPPC64ShiftMaskLength(v int64) int64 {
14 return int64(bits.Len64(uint64(v)))
15 }
16
17
18
19
20 func isPPC64WordRotateMaskNonWrapping(v64 int64) bool {
21
22 v := uint32(v64)
23 vp := (v & -v) + v
24 return (v&vp == 0) && v != 0 && uint64(uint32(v64)) == uint64(v64)
25 }
26
27
28 func isU16Bit(n int64) bool {
29 return n == int64(uint16(n))
30 }
31
32
33
34 func mergePPC64AndRlwinm(mask uint32, rlw int64) int64 {
35 r, _, _, mask_rlw := ssa.DecodePPC64RotateMask(rlw)
36 mask_out := (mask_rlw & uint64(mask))
37
38
39 if !ssa.IsPPC64WordRotateMask(int64(mask_out)) {
40 return 0
41 }
42 return ssa.EncodePPC64RotateMask(r, int64(mask_out), 32)
43 }
44
45
46 func mergePPC64AndSldi(m, s int64) int64 {
47 mask := -1 << s & m
48
49
50 rv := bits.RotateLeft64(0xFFFFFFFF00000000, int(s))
51 if rv&uint64(mask) != 0 {
52 return 0
53 }
54 if !isPPC64WordRotateMaskNonWrapping(mask) {
55 return 0
56 }
57 return ssa.EncodePPC64RotateMask(s&31, mask, 32)
58 }
59
60
61 func mergePPC64AndSrdi(m, s int64) int64 {
62 mask := ssa.MergePPC64RShiftMask(m, s, 64)
63
64
65 rv := bits.RotateLeft64(0xFFFFFFFF00000000, -int(s))
66 if rv&uint64(mask) != 0 {
67 return 0
68 }
69 if !isPPC64WordRotateMaskNonWrapping(mask) {
70 return 0
71 }
72 return ssa.EncodePPC64RotateMask((32-s)&31, mask, 32)
73 }
74
75
76
77 func mergePPC64ClrlsldiSrd(sld, srd int64) int64 {
78 mask_1 := uint64(0xFFFFFFFFFFFFFFFF) >> uint(srd)
79
80 mask_2 := uint64(0xFFFFFFFFFFFFFFFF) >> uint(ssa.GetPPC64Shiftmb(sld))
81
82
83 mask_3 := (mask_1 & mask_2) << uint(ssa.GetPPC64Shiftsh(sld))
84
85 r_1 := 64 - srd
86 r_2 := ssa.GetPPC64Shiftsh(sld)
87 r_3 := (r_1 + r_2) & 63
88
89 if uint64(uint32(mask_3)) != mask_3 || mask_3 == 0 {
90 return 0
91 }
92
93 v1 := bits.RotateLeft64(0xFFFFFFFF00000000, int(r_3))
94 if v1&mask_3 != 0 {
95 return 0
96 }
97 return ssa.EncodePPC64RotateMask(r_3&31, int64(mask_3), 32)
98 }
99
100
101
102 func mergePPC64MovwzregRlwinm(rlw int64) int64 {
103 _, mb, me, _ := ssa.DecodePPC64RotateMask(rlw)
104 if mb > me {
105 return 0
106 }
107 return rlw
108 }
109
110
111
112 func mergePPC64RlwinmAnd(rlw int64, mask uint32) int64 {
113 r, _, _, mask_rlw := ssa.DecodePPC64RotateMask(rlw)
114
115
116 r_mask := bits.RotateLeft32(mask, int(r))
117
118 mask_out := (mask_rlw & uint64(r_mask))
119
120
121 if !ssa.IsPPC64WordRotateMask(int64(mask_out)) {
122 return 0
123 }
124 return ssa.EncodePPC64RotateMask(r, int64(mask_out), 32)
125 }
126
127
128
129 func mergePPC64SldiRlwinm(sldi, rlw int64) int64 {
130 r_1, mb, me, mask_1 := ssa.DecodePPC64RotateMask(rlw)
131 if mb > me || mb < sldi {
132
133
134 return 0
135 }
136
137 mask_3 := mask_1 << sldi
138 r_3 := (r_1 + sldi) & 31
139
140
141 if uint64(uint32(mask_3)) != mask_3 {
142 return 0
143 }
144 return ssa.EncodePPC64RotateMask(r_3, int64(mask_3), 32)
145 }
146
147
148 func rotateLeft32(v, rotate int64) int64 {
149 return int64(bits.RotateLeft32(uint32(v), int(rotate)))
150 }
151
View as plain text