llvm.org GIT mirror llvm / 61ed5dd
Add 64-bit load and store instructions. There is only a few new instructions, the rest is handled with patterns. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178528 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 7 years ago
2 changed file(s) with 126 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
170170 def : Pat<(sub i64:$a, (i64 simm13:$b)), (SUBri $a, (as_i32imm $b))>;
171171
172172 } // Predicates = [Is64Bit]
173
174
175 //===----------------------------------------------------------------------===//
176 // 64-bit Loads and Stores.
177 //===----------------------------------------------------------------------===//
178 //
179 // All the 32-bit loads and stores are available. The extending loads are sign
180 // or zero-extending to 64 bits. The LDrr and LDri instructions load 32 bits
181 // zero-extended to i64. Their mnemonic is lduw in SPARC v9 (Load Unsigned
182 // Word).
183 //
184 // SPARC v9 adds 64-bit loads as well as a sign-extending ldsw i32 loads.
185
186 let Predicates = [Is64Bit] in {
187
188 // 64-bit loads.
189 def LDXrr : F3_1<3, 0b001011,
190 (outs I64Regs:$dst), (ins MEMrr:$addr),
191 "ldx [$addr], $dst",
192 [(set i64:$dst, (load ADDRrr:$addr))]>;
193 def LDXri : F3_2<3, 0b001011,
194 (outs I64Regs:$dst), (ins MEMri:$addr),
195 "ldx [$addr], $dst",
196 [(set i64:$dst, (load ADDRri:$addr))]>;
197
198 // Extending loads to i64.
199 def : Pat<(i64 (zextloadi8 ADDRrr:$addr)), (LDUBrr ADDRrr:$addr)>;
200 def : Pat<(i64 (zextloadi8 ADDRri:$addr)), (LDUBri ADDRri:$addr)>;
201 def : Pat<(i64 (sextloadi8 ADDRrr:$addr)), (LDSBrr ADDRrr:$addr)>;
202 def : Pat<(i64 (sextloadi8 ADDRri:$addr)), (LDSBri ADDRri:$addr)>;
203
204 def : Pat<(i64 (zextloadi16 ADDRrr:$addr)), (LDUHrr ADDRrr:$addr)>;
205 def : Pat<(i64 (zextloadi16 ADDRri:$addr)), (LDUHri ADDRri:$addr)>;
206 def : Pat<(i64 (sextloadi16 ADDRrr:$addr)), (LDSHrr ADDRrr:$addr)>;
207 def : Pat<(i64 (sextloadi16 ADDRri:$addr)), (LDSHri ADDRri:$addr)>;
208
209 def : Pat<(i64 (zextloadi32 ADDRrr:$addr)), (LDrr ADDRrr:$addr)>;
210 def : Pat<(i64 (zextloadi32 ADDRri:$addr)), (LDri ADDRri:$addr)>;
211
212 // Sign-extending load of i32 into i64 is a new SPARC v9 instruction.
213 def LDSWrr : F3_1<3, 0b001011,
214 (outs I64Regs:$dst), (ins MEMrr:$addr),
215 "ldsw [$addr], $dst",
216 [(set i64:$dst, (sextloadi32 ADDRrr:$addr))]>;
217 def LDSWri : F3_2<3, 0b001011,
218 (outs I64Regs:$dst), (ins MEMri:$addr),
219 "ldsw [$addr], $dst",
220 [(set i64:$dst, (sextloadi32 ADDRri:$addr))]>;
221
222 // 64-bit stores.
223 def STXrr : F3_1<3, 0b001110,
224 (outs), (ins MEMrr:$addr, I64Regs:$src),
225 "stx $src, [$addr]",
226 [(store i64:$src, ADDRrr:$addr)]>;
227 def STXri : F3_2<3, 0b001110,
228 (outs), (ins MEMri:$addr, I64Regs:$src),
229 "stx $src, [$addr]",
230 [(store i64:$src, ADDRri:$addr)]>;
231
232 // Truncating stores from i64 are identical to the i32 stores.
233 def : Pat<(truncstorei8 i64:$src, ADDRrr:$addr), (STBrr ADDRrr:$addr, $src)>;
234 def : Pat<(truncstorei8 i64:$src, ADDRri:$addr), (STBri ADDRri:$addr, $src)>;
235 def : Pat<(truncstorei16 i64:$src, ADDRrr:$addr), (STHrr ADDRrr:$addr, $src)>;
236 def : Pat<(truncstorei16 i64:$src, ADDRri:$addr), (STHri ADDRri:$addr, $src)>;
237 def : Pat<(truncstorei32 i64:$src, ADDRrr:$addr), (STrr ADDRrr:$addr, $src)>;
238 def : Pat<(truncstorei32 i64:$src, ADDRri:$addr), (STri ADDRri:$addr, $src)>;
239
240 } // Predicates = [Is64Bit]
8585 %b = xor i64 %a, 2
8686 ret i64 %b
8787 }
88
89 ; CHECK: loads
90 ; CHECK: ldx [%i0]
91 ; CHECK: stx %
92 ; CHECK: ld [%i1]
93 ; CHECK: st %
94 ; CHECK: ldsw [%i2]
95 ; CHECK: stx %
96 ; CHECK: ldsh [%i3]
97 ; CHECK: sth %
98 define i64 @loads(i64* %p, i32* %q, i32* %r, i16* %s) {
99 %a = load i64* %p
100 %ai = add i64 1, %a
101 store i64 %ai, i64* %p
102 %b = load i32* %q
103 %b2 = zext i32 %b to i64
104 %bi = trunc i64 %ai to i32
105 store i32 %bi, i32* %q
106 %c = load i32* %r
107 %c2 = sext i32 %c to i64
108 store i64 %ai, i64* %p
109 %d = load i16* %s
110 %d2 = sext i16 %d to i64
111 %di = trunc i64 %ai to i16
112 store i16 %di, i16* %s
113
114 %x1 = add i64 %a, %b2
115 %x2 = add i64 %c2, %d2
116 %x3 = add i64 %x1, %x2
117 ret i64 %x3
118 }
119
120 ; CHECK: stores
121 ; CHECK: ldx [%i0+8], [[R:%[goli][0-7]]]
122 ; CHECK: stx [[R]], [%i0+16]
123 ; CHECK: st [[R]], [%i1+-8]
124 ; CHECK: sth [[R]], [%i2+40]
125 ; CHECK: stb [[R]], [%i3+-20]
126 define void @stores(i64* %p, i32* %q, i16* %r, i8* %s) {
127 %p1 = getelementptr i64* %p, i64 1
128 %p2 = getelementptr i64* %p, i64 2
129 %pv = load i64* %p1
130 store i64 %pv, i64* %p2
131
132 %q2 = getelementptr i32* %q, i32 -2
133 %qv = trunc i64 %pv to i32
134 store i32 %qv, i32* %q2
135
136 %r2 = getelementptr i16* %r, i16 20
137 %rv = trunc i64 %pv to i16
138 store i16 %rv, i16* %r2
139
140 %s2 = getelementptr i8* %s, i8 -20
141 %sv = trunc i64 %pv to i8
142 store i8 %sv, i8* %s2
143
144 ret void
145 }