Deleted Added
sdiff udiff text old ( 200581 ) new ( 201360 )
full compact
1//===- ARMInstrThumb2.td - Thumb2 support for ARM -------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//

--- 151 unchanged lines hidden (view full) ---

160
161//===----------------------------------------------------------------------===//
162// Multiclass helpers...
163//
164
165/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
166/// unary operation that produces a value. These are predicable and can be
167/// changed to modify CPSR.
168multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{
169 // shifted imm
170 def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
171 opc, "\t$dst, $src",
172 [(set GPR:$dst, (opnode t2_so_imm:$src))]> {
173 let isAsCheapAsAMove = Cheap;
174 let isReMaterializable = ReMat;
175 }
176 // register
177 def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
178 opc, ".w\t$dst, $src",
179 [(set GPR:$dst, (opnode GPR:$src))]>;
180 // shifted register
181 def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iMOVsi,
182 opc, ".w\t$dst, $src",
183 [(set GPR:$dst, (opnode t2_so_reg:$src))]>;
184}
185
186/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
187// binary operation that produces a value. These are predicable and can be
188/// changed to modify CPSR.
189multiclass T2I_bin_irs190 bit Commutable = 0, string wide =""> {
191 // shifted imm
192 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
193 opc, "\t$dst, $lhs, $rhs",
194 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
195 // register
196 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
197 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
198 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
199 let isCommutable = Commutable;
200 }
201 // shifted register
202 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
203 opc, !strconcat(wide, "\t$dst, $lhs, $rhs"),
204 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
205}
206
207/// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
208// the ".w" prefix to indicate that they are wide.
209multiclass T2I_bin_w_irs<string opc, PatFrag opnode, bit Commutable = 0> :
210 T2I_bin_irs<opc, opnode, Commutable, ".w">;
211
212/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
213/// reversed. It doesn't define the 'rr' form since it's handled by its
214/// T2I_bin_irs counterpart.
215multiclass T2I_rbin_is {
216 // shifted imm
217 def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALUi,
218 opc, ".w\t$dst, $rhs, $lhs",
219 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
220 // shifted register
221 def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALUsi,
222 opc, "\t$dst, $rhs, $lhs",
223 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
224}
225
226/// T2I_bin_s_irs - Similar to T2I_bin_irs except it sets the 's' bit so the
227/// instruction modifies the CPSR register.
228let Defs = [CPSR] in {
229multiclass T2I_bin_s_irs<string opc, PatFrag opnode, bit Commutable = 0> {
230 // shifted imm
231 def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
232 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
233 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
234 // register
235 def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
236 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
237 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
238 let isCommutable = Commutable;
239 }
240 // shifted register
241 def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
242 !strconcat(opc, "s"), ".w\t$dst, $lhs, $rhs",
243 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
244}
245}
246
247/// T2I_bin_ii12rs - Defines a set of (op reg, {so_imm|imm0_4095|r|so_reg})
248/// patterns for a binary operation that produces a value.
249multiclass T2I_bin_ii12rs<string opc, PatFrag opnode, bit Commutable = 0> {
250 // shifted imm
251 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
252 opc, ".w\t$dst, $lhs, $rhs",
253 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
254 // 12-bit imm
255 def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, imm0_4095:$rhs), IIC_iALUi,
256 !strconcat(opc, "w"), "\t$dst, $lhs, $rhs",
257 [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>;
258 // register
259 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
260 opc, ".w\t$dst, $lhs, $rhs",
261 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
262 let isCommutable = Commutable;
263 }
264 // shifted register
265 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
266 opc, ".w\t$dst, $lhs, $rhs",
267 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
268}
269
270/// T2I_adde_sube_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns
271/// for a binary operation that produces a value and use and define the carry
272/// bit. It's not predicable.
273let Uses = [CPSR] in {
274multiclass T2I_adde_sube_irs {
275 // shifted imm
276 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
277 opc, "\t$dst, $lhs, $rhs",
278 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
279 Requires<[IsThumb2, CarryDefIsUnused]>;
280 // register
281 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
282 opc, ".w\t$dst, $lhs, $rhs",
283 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
284 Requires<[IsThumb2, CarryDefIsUnused]> {
285 let isCommutable = Commutable;
286 }
287 // shifted register
288 def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
289 opc, ".w\t$dst, $lhs, $rhs",
290 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
291 Requires<[IsThumb2, CarryDefIsUnused]>;
292 // Carry setting variants
293 // shifted imm
294 def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALUi,
295 !strconcat(opc, "s\t$dst, $lhs, $rhs"),
296 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
297 Requires<[IsThumb2, CarryDefIsUsed]> {
298 let Defs = [CPSR];
299 }
300 // register
301 def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
302 !strconcat(opc, "s.w\t$dst, $lhs, $rhs"),
303 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
304 Requires<[IsThumb2, CarryDefIsUsed]> {
305 let Defs = [CPSR];
306 let isCommutable = Commutable;
307 }
308 // shifted register
309 def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALUsi,
310 !strconcat(opc, "s.w\t$dst, $lhs, $rhs"),
311 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
312 Requires<[IsThumb2, CarryDefIsUsed]> {
313 let Defs = [CPSR];
314 }
315}
316}
317
318/// T2I_rbin_s_is - Same as T2I_rbin_is except sets 's' bit.
319let Defs = [CPSR] in {
320multiclass T2I_rbin_s_is {
321 // shifted imm
322 def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
323 IIC_iALUi,
324 !strconcat(opc, "${s}.w\t$dst, $rhs, $lhs"),
325 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
326 // shifted register
327 def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s),
328 IIC_iALUsi,
329 !strconcat(opc, "${s}\t$dst, $rhs, $lhs"),
330 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
331}
332}
333
334/// T2I_sh_ir - Defines a set of (op reg, {so_imm|r}) patterns for a shift /
335// rotate operation that produces a value.
336multiclass T2I_sh_ir {
337 // 5-bit imm
338 def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
339 opc, ".w\t$dst, $lhs, $rhs",
340 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>;
341 // register
342 def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iMOVsr,
343 opc, ".w\t$dst, $lhs, $rhs",
344 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
345}
346
347/// T2I_cmp_is - Defines a set of (op r, {so_imm|r|so_reg}) cmp / test
348/// patterns. Similar to T2I_bin_irs except the instruction does not produce
349/// a explicit result, only implicitly set CPSR.
350let Defs = [CPSR] in {
351multiclass T2I_cmp_is<string opc, PatFrag opnode> {
352 // shifted imm
353 def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iCMPi,
354 opc, ".w\t$lhs, $rhs",
355 [(opnode GPR:$lhs, t2_so_imm:$rhs)]>;
356 // register
357 def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
358 opc, ".w\t$lhs, $rhs",
359 [(opnode GPR:$lhs, GPR:$rhs)]>;
360 // shifted register
361 def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iCMPsi,
362 opc, ".w\t$lhs, $rhs",
363 [(opnode GPR:$lhs, t2_so_reg:$rhs)]>;
364}
365}
366
367/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
368multiclass T2I_ld {
369 def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), IIC_iLoadi,
370 opc, ".w\t$dst, $addr",
371 [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>;
372 def i8 : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoadi,
373 opc, "\t$dst, $addr",
374 [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>;
375 def s : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), IIC_iLoadr,
376 opc, ".w\t$dst, $addr",
377 [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]>;
378 def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
379 opc, ".w\t$dst, $addr",
380 [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]> {
381 let isReMaterializable = 1;
382 }
383}
384
385/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
386multiclass T2I_st {
387 def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), IIC_iStorei,
388 opc, ".w\t$src, $addr",
389 [(opnode GPR:$src, t2addrmode_imm12:$addr)]>;
390 def i8 : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), IIC_iStorei,
391 opc, "\t$src, $addr",
392 [(opnode GPR:$src, t2addrmode_imm8:$addr)]>;
393 def s : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), IIC_iStorer,
394 opc, ".w\t$src, $addr",
395 [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>;
396}
397
398/// T2I_picld - Defines the PIC load pattern.
399class T2I_picld<string opc, PatFrag opnode> :
400 T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoadi,
401 !strconcat("\n${addr:label}:\n\t", opc), "\t$dst, $addr",
402 [(set GPR:$dst, (opnode addrmodepc:$addr))]>;
403
404/// T2I_picst - Defines the PIC store pattern.
405class T2I_picst<string opc, PatFrag opnode> :
406 T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStorer,
407 !strconcat("\n${addr:label}:\n\t", opc), "\t$src, $addr",
408 [(opnode GPR:$src, addrmodepc:$addr)]>;
409
410
411/// T2I_unary_rrot - A unary operation with two forms: one whose operand is a
412/// register and one whose operand is a register rotated by 8/16/24.
413multiclass T2I_unary_rrot {
414 def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
415 opc, ".w\t$dst, $src",
416 [(set GPR:$dst, (opnode GPR:$src))]>;
417 def r_rot : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$rot), IIC_iUNAsi,
418 opc, ".w\t$dst, $src, ror $rot",
419 [(set GPR:$dst, (opnode (rotr GPR:$src, rot_imm:$rot)))]>;
420}
421
422/// T2I_bin_rrot - A binary operation with two forms: one whose operand is a
423/// register and one whose operand is a register rotated by 8/16/24.
424multiclass T2I_bin_rrot {
425 def rr : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALUr,
426 opc, "\t$dst, $LHS, $RHS",
427 [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>;
428 def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
429 IIC_iALUsr, opc, "\t$dst, $LHS, $RHS, ror $rot",
430 [(set GPR:$dst, (opnode GPR:$LHS,
431 (rotr GPR:$RHS, rot_imm:$rot)))]>;
432}
433
434//===----------------------------------------------------------------------===//
435// Instructions
436//===----------------------------------------------------------------------===//
437
438//===----------------------------------------------------------------------===//
439// Miscellaneous Instructions.
440//
441
442// LEApcrel - Load a pc-relative address into a register without offending the
443// assembler.
444def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
445 "adr$p.w\t$dst, #$label", []>;
446
447def t2LEApcrelJT : T2XI<(outs GPR:$dst),
448 (ins i32imm:$label, nohash_imm:$id, pred:$p), IIC_iALUi,
449 "adr$p.w\t$dst, #${label}_${id}", []>;
450
451// ADD r, sp, {so_imm|i12}
452def t2ADDrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
453 IIC_iALUi, "add", ".w\t$dst, $sp, $imm", []>;
454def t2ADDrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
455 IIC_iALUi, "addw", "\t$dst, $sp, $imm", []>;
456
457// ADD r, sp, so_reg
458def t2ADDrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
459 IIC_iALUsi, "add", ".w\t$dst, $sp, $rhs", []>;
460
461// SUB r, sp, {so_imm|i12}
462def t2SUBrSPi : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
463 IIC_iALUi, "sub", ".w\t$dst, $sp, $imm", []>;
464def t2SUBrSPi12 : T2I<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
465 IIC_iALUi, "subw", "\t$dst, $sp, $imm", []>;
466
467// SUB r, sp, so_reg
468def t2SUBrSPs : T2sI<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
469 IIC_iALUsi,
470 "sub", "\t$dst, $sp, $rhs", []>;
471
472
473// Pseudo instruction that will expand into a t2SUBrSPi + a copy.
474let usesCustomInserter = 1 in { // Expanded after instruction selection.
475def t2SUBrSPi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_imm:$imm),
476 NoItinerary, "@ sub.w\t$dst, $sp, $imm", []>;
477def t2SUBrSPi12_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, imm0_4095:$imm),
478 NoItinerary, "@ subw\t$dst, $sp, $imm", []>;
479def t2SUBrSPs_ : PseudoInst<(outs GPR:$dst), (ins GPR:$sp, t2_so_reg:$rhs),
480 NoItinerary, "@ sub\t$dst, $sp, $rhs", []>;
481} // usesCustomInserter
482
483
484//===----------------------------------------------------------------------===//
485// Load / store Instructions.
486//
487
488// Load
489let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
490defm t2LDR : T2I_ld<"ldr", UnOpFrag<(load node:$Src)>>;
491
492// Loads with zero extension
493defm t2LDRH : T2I_ld<"ldrh", UnOpFrag<(zextloadi16 node:$Src)>>;
494defm t2LDRB : T2I_ld<"ldrb", UnOpFrag<(zextloadi8 node:$Src)>>;
495
496// Loads with sign extension
497defm t2LDRSH : T2I_ld<"ldrsh", UnOpFrag<(sextloadi16 node:$Src)>>;
498defm t2LDRSB : T2I_ld<"ldrsb", UnOpFrag<(sextloadi8 node:$Src)>>;
499
500let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
501// Load doubleword
502def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2),
503 (ins t2addrmode_imm8s4:$addr),
504 IIC_iLoadi, "ldrd", "\t$dst1, $addr", []>;
505def t2LDRDpci : T2Ii8s4<(outs GPR:$dst1, GPR:$dst2),
506 (ins i32imm:$addr), IIC_iLoadi,
507 "ldrd", "\t$dst1, $addr", []>;
508}
509
510// zextload i1 -> zextload i8
511def : T2Pat<(zextloadi1 t2addrmode_imm12:$addr),
512 (t2LDRBi12 t2addrmode_imm12:$addr)>;
513def : T2Pat<(zextloadi1 t2addrmode_imm8:$addr),
514 (t2LDRBi8 t2addrmode_imm8:$addr)>;
515def : T2Pat<(zextloadi1 t2addrmode_so_reg:$addr),
516 (t2LDRBs t2addrmode_so_reg:$addr)>;

--- 27 unchanged lines hidden (view full) ---

544 (t2LDRHi8 t2addrmode_imm8:$addr)>;
545def : T2Pat<(extloadi16 t2addrmode_so_reg:$addr),
546 (t2LDRHs t2addrmode_so_reg:$addr)>;
547def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
548 (t2LDRHpci tconstpool:$addr)>;
549
550// Indexed loads
551let mayLoad = 1 in {
552def t2LDR_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
553 (ins t2addrmode_imm8:$addr),
554 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
555 "ldr", "\t$dst, $addr!", "$addr.base = $base_wb",
556 []>;
557
558def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
559 (ins GPR:$base, t2am_imm8_offset:$offset),
560 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
561 "ldr", "\t$dst, [$base], $offset", "$base = $base_wb",
562 []>;
563
564def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
565 (ins t2addrmode_imm8:$addr),
566 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
567 "ldrb", "\t$dst, $addr!", "$addr.base = $base_wb",
568 []>;
569def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
570 (ins GPR:$base, t2am_imm8_offset:$offset),
571 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
572 "ldrb", "\t$dst, [$base], $offset", "$base = $base_wb",
573 []>;
574
575def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
576 (ins t2addrmode_imm8:$addr),
577 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
578 "ldrh", "\t$dst, $addr!", "$addr.base = $base_wb",
579 []>;
580def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
581 (ins GPR:$base, t2am_imm8_offset:$offset),
582 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
583 "ldrh", "\t$dst, [$base], $offset", "$base = $base_wb",
584 []>;
585
586def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
587 (ins t2addrmode_imm8:$addr),
588 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
589 "ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb",
590 []>;
591def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
592 (ins GPR:$base, t2am_imm8_offset:$offset),
593 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
594 "ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb",
595 []>;
596
597def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
598 (ins t2addrmode_imm8:$addr),
599 AddrModeT2_i8, IndexModePre, IIC_iLoadiu,
600 "ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb",
601 []>;
602def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
603 (ins GPR:$base, t2am_imm8_offset:$offset),
604 AddrModeT2_i8, IndexModePost, IIC_iLoadiu,
605 "ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb",
606 []>;
607}
608
609// Store
610defm t2STR : T2I_st<"str", BinOpFrag<(store node:$LHS, node:$RHS)>>;
611defm t2STRB : T2I_st<"strb", BinOpFrag<(truncstorei8 node:$LHS, node:$RHS)>>;
612defm t2STRH : T2I_st<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
613
614// Store doubleword
615let mayLoad = 1, hasExtraSrcRegAllocReq = 1 in
616def t2STRDi8 : T2Ii8s4<(outs),
617 (ins GPR:$src1, GPR:$src2, t2addrmode_imm8s4:$addr),
618 IIC_iStorer, "strd", "\t$src1, $addr", []>;
619
620// Indexed stores
621def t2STR_PRE : T2Iidxldst<(outs GPR:$base_wb),
622 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
623 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
624 "str", "\t$src, [$base, $offset]!", "$base = $base_wb",
625 [(set GPR:$base_wb,
626 (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
627
628def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb),
629 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
630 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
631 "str", "\t$src, [$base], $offset", "$base = $base_wb",
632 [(set GPR:$base_wb,
633 (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
634
635def t2STRH_PRE : T2Iidxldst<(outs GPR:$base_wb),
636 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
637 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
638 "strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
639 [(set GPR:$base_wb,
640 (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
641
642def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb),
643 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
644 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
645 "strh", "\t$src, [$base], $offset", "$base = $base_wb",
646 [(set GPR:$base_wb,
647 (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
648
649def t2STRB_PRE : T2Iidxldst<(outs GPR:$base_wb),
650 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
651 AddrModeT2_i8, IndexModePre, IIC_iStoreiu,
652 "strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
653 [(set GPR:$base_wb,
654 (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
655
656def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb),
657 (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
658 AddrModeT2_i8, IndexModePost, IIC_iStoreiu,
659 "strb", "\t$src, [$base], $offset", "$base = $base_wb",
660 [(set GPR:$base_wb,
661 (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
662
663
664// FIXME: ldrd / strd pre / post variants
665
666//===----------------------------------------------------------------------===//
667// Load / store multiple Instructions.
668//
669
670let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
671def t2LDM : T2XI<(outs),
672 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
673 IIC_iLoadm, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb", []>;
674
675let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
676def t2STM : T2XI<(outs),
677 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
678 IIC_iStorem, "stm${addr:submode}${p}${addr:wide}\t$addr, $wb", []>;
679
680//===----------------------------------------------------------------------===//
681// Move Instructions.
682//
683
684let neverHasSideEffects = 1 in
685def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
686 "mov", ".w\t$dst, $src", []>;
687
688// AddedComplexity to ensure isel tries t2MOVi before t2MOVi16.
689let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = 1 in
690def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iMOVi,
691 "mov", ".w\t$dst, $src",
692 [(set GPR:$dst, t2_so_imm:$src)]>;
693
694let isReMaterializable = 1, isAsCheapAsAMove = 1 in
695def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iMOVi,
696 "movw", "\t$dst, $src",
697 [(set GPR:$dst, imm0_65535:$src)]>;
698
699let Constraints = "$src = $dst" in
700def t2MOVTi16 : T2I<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iMOVi,
701 "movt", "\t$dst, $imm",
702 [(set GPR:$dst,
703 (or (and GPR:$src, 0xffff), lo16AllZero:$imm))]>;
704
705def : T2Pat<(or GPR:$src, 0xffff0000), (t2MOVTi16 GPR:$src, 0xffff)>;
706
707//===----------------------------------------------------------------------===//
708// Extend Instructions.
709//
710
711// Sign extenders
712
713defm t2SXTB : T2I_unary_rrot<"sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
714defm t2SXTH : T2I_unary_rrot<"sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
715
716defm t2SXTAB : T2I_bin_rrot<"sxtab",
717 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
718defm t2SXTAH : T2I_bin_rrot<"sxtah",
719 BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
720
721// TODO: SXT(A){B|H}16
722
723// Zero extenders
724
725let AddedComplexity = 16 in {
726defm t2UXTB : T2I_unary_rrot<"uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
727defm t2UXTH : T2I_unary_rrot<"uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
728defm t2UXTB16 : T2I_unary_rrot<"uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
729
730def : T2Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
731 (t2UXTB16r_rot GPR:$Src, 24)>;
732def : T2Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
733 (t2UXTB16r_rot GPR:$Src, 8)>;
734
735defm t2UXTAB : T2I_bin_rrot<"uxtab",
736 BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
737defm t2UXTAH : T2I_bin_rrot<"uxtah",
738 BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
739}
740
741//===----------------------------------------------------------------------===//
742// Arithmetic Instructions.
743//
744
745defm t2ADD : T2I_bin_ii12rs<"add", BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
746defm t2SUB : T2I_bin_ii12rs<"sub", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
747
748// ADD and SUB with 's' bit set. No 12-bit immediate (T4) variants.
749defm t2ADDS : T2I_bin_s_irs <"add", BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
750defm t2SUBS : T2I_bin_s_irs <"sub", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
751
752defm t2ADC : T2I_adde_sube_irs<"adc",BinOpFrag<(adde node:$LHS, node:$RHS)>,1>;
753defm t2SBC : T2I_adde_sube_irs<"sbc",BinOpFrag<(sube node:$LHS, node:$RHS)>>;
754
755// RSB
756defm t2RSB : T2I_rbin_is <"rsb", BinOpFrag<(sub node:$LHS, node:$RHS)>>;
757defm t2RSBS : T2I_rbin_s_is <"rsb", BinOpFrag<(subc node:$LHS, node:$RHS)>>;
758
759// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
760let AddedComplexity = 1 in
761def : T2Pat<(add GPR:$src, imm0_255_neg:$imm),
762 (t2SUBri GPR:$src, imm0_255_neg:$imm)>;
763def : T2Pat<(add GPR:$src, t2_so_imm_neg:$imm),
764 (t2SUBri GPR:$src, t2_so_imm_neg:$imm)>;
765def : T2Pat<(add GPR:$src, imm0_4095_neg:$imm),
766 (t2SUBri12 GPR:$src, imm0_4095_neg:$imm)>;
767
768
769//===----------------------------------------------------------------------===//
770// Shift and rotate Instructions.
771//
772
773defm t2LSL : T2I_sh_ir<"lsl", BinOpFrag<(shl node:$LHS, node:$RHS)>>;
774defm t2LSR : T2I_sh_ir<"lsr", BinOpFrag<(srl node:$LHS, node:$RHS)>>;
775defm t2ASR : T2I_sh_ir<"asr", BinOpFrag<(sra node:$LHS, node:$RHS)>>;
776defm t2ROR : T2I_sh_ir<"ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
777
778let Uses = [CPSR] in {
779def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
780 "rrx", "\t$dst, $src",
781 [(set GPR:$dst, (ARMrrx GPR:$src))]>;
782}
783
784let Defs = [CPSR] in {
785def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
786 "lsrs.w\t$dst, $src, #1",
787 [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>;
788def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi,
789 "asrs.w\t$dst, $src, #1",
790 [(set GPR:$dst, (ARMsra_flag GPR:$src))]>;
791}
792
793//===----------------------------------------------------------------------===//
794// Bitwise Instructions.
795//
796
797defm t2AND : T2I_bin_w_irs<"and", BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
798defm t2ORR : T2I_bin_w_irs<"orr", BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
799defm t2EOR : T2I_bin_w_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
800
801defm t2BIC : T2I_bin_w_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
802
803let Constraints = "$src = $dst" in
804def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
805 IIC_iUNAsi, "bfc", "\t$dst, $imm",
806 [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>;
807
808def t2SBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
809 IIC_iALUi, "sbfx", "\t$dst, $src, $lsb, $width", []>;
810
811def t2UBFX : T2I<(outs GPR:$dst), (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
812 IIC_iALUi, "ubfx", "\t$dst, $src, $lsb, $width", []>;
813
814// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
815
816defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
817
818// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
819let AddedComplexity = 1 in
820defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
821
822
823def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
824 (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
825
826// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
827def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
828 (t2ORNri GPR:$src, t2_so_imm_not:$imm)>,
829 Requires<[IsThumb2]>;
830
831def : T2Pat<(t2_so_imm_not:$src),
832 (t2MVNi t2_so_imm_not:$src)>;
833
834//===----------------------------------------------------------------------===//
835// Multiply Instructions.
836//
837let isCommutable = 1 in
838def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
839 "mul", "\t$dst, $a, $b",
840 [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
841
842def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
843 "mla", "\t$dst, $a, $b, $c",
844 [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
845
846def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
847 "mls", "\t$dst, $a, $b, $c",
848 [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>;
849
850// Extra precision multiplies with low / high results
851let neverHasSideEffects = 1 in {
852let isCommutable = 1 in {
853def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
854 "smull", "\t$ldst, $hdst, $a, $b", []>;
855
856def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMUL64,
857 "umull", "\t$ldst, $hdst, $a, $b", []>;
858}
859
860// Multiply + accumulate
861def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
862 "smlal", "\t$ldst, $hdst, $a, $b", []>;
863
864def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
865 "umlal", "\t$ldst, $hdst, $a, $b", []>;
866
867def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iMAC64,
868 "umaal", "\t$ldst, $hdst, $a, $b", []>;
869} // neverHasSideEffects
870
871// Most significant word multiply
872def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
873 "smmul", "\t$dst, $a, $b",
874 [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>;
875
876def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
877 "smmla", "\t$dst, $a, $b, $c",
878 [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>;
879
880
881def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iMAC32,
882 "smmls", "\t$dst, $a, $b, $c",
883 [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>;
884
885multiclass T2I_smul<string opc, PatFrag opnode> {
886 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
887 !strconcat(opc, "bb"), "\t$dst, $a, $b",
888 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
889 (sext_inreg GPR:$b, i16)))]>;
890
891 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
892 !strconcat(opc, "bt"), "\t$dst, $a, $b",
893 [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
894 (sra GPR:$b, (i32 16))))]>;
895
896 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
897 !strconcat(opc, "tb"), "\t$dst, $a, $b",
898 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
899 (sext_inreg GPR:$b, i16)))]>;
900
901 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL32,
902 !strconcat(opc, "tt"), "\t$dst, $a, $b",
903 [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
904 (sra GPR:$b, (i32 16))))]>;
905
906 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
907 !strconcat(opc, "wb"), "\t$dst, $a, $b",
908 [(set GPR:$dst, (sra (opnode GPR:$a,
909 (sext_inreg GPR:$b, i16)), (i32 16)))]>;
910
911 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iMUL16,
912 !strconcat(opc, "wt"), "\t$dst, $a, $b",
913 [(set GPR:$dst, (sra (opnode GPR:$a,
914 (sra GPR:$b, (i32 16))), (i32 16)))]>;
915}
916
917
918multiclass T2I_smla<string opc, PatFrag opnode> {
919 def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
920 !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
921 [(set GPR:$dst, (add GPR:$acc,
922 (opnode (sext_inreg GPR:$a, i16),
923 (sext_inreg GPR:$b, i16))))]>;
924
925 def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
926 !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
927 [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
928 (sra GPR:$b, (i32 16)))))]>;
929
930 def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
931 !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
932 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
933 (sext_inreg GPR:$b, i16))))]>;
934
935 def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
936 !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
937 [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
938 (sra GPR:$b, (i32 16)))))]>;
939
940 def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
941 !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
942 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
943 (sext_inreg GPR:$b, i16)), (i32 16))))]>;
944
945 def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iMAC16,
946 !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
947 [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
948 (sra GPR:$b, (i32 16))), (i32 16))))]>;
949}
950
951defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
952defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
953
954// TODO: Halfword multiple accumulate long: SMLAL<x><y>
955// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
956
957
958//===----------------------------------------------------------------------===//
959// Misc. Arithmetic Instructions.
960//
961
962def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
963 "clz", "\t$dst, $src",
964 [(set GPR:$dst, (ctlz GPR:$src))]>;
965
966def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
967 "rev", ".w\t$dst, $src",
968 [(set GPR:$dst, (bswap GPR:$src))]>;
969
970def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
971 "rev16", ".w\t$dst, $src",
972 [(set GPR:$dst,
973 (or (and (srl GPR:$src, (i32 8)), 0xFF),
974 (or (and (shl GPR:$src, (i32 8)), 0xFF00),
975 (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
976 (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
977
978def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
979 "revsh", ".w\t$dst, $src",
980 [(set GPR:$dst,
981 (sext_inreg
982 (or (srl (and GPR:$src, 0xFF00), (i32 8)),
983 (shl GPR:$src, (i32 8))), i16))]>;
984
985def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
986 IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
987 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
988 (and (shl GPR:$src2, (i32 imm:$shamt)),
989 0xFFFF0000)))]>;
990
991// Alternate cases for PKHBT where identities eliminate some nodes.
992def : T2Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
993 (t2PKHBT GPR:$src1, GPR:$src2, 0)>;
994def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
995 (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
996
997def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
998 IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
999 [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
1000 (and (sra GPR:$src2, imm16_31:$shamt),
1001 0xFFFF)))]>;
1002
1003// Alternate cases for PKHTB where identities eliminate some nodes. Note that
1004// a shift amount of 0 is *not legal* here, it is PKHBT instead.
1005def : T2Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
1006 (t2PKHTB GPR:$src1, GPR:$src2, 16)>;
1007def : T2Pat<(or (and GPR:$src1, 0xFFFF0000),
1008 (and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
1009 (t2PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
1010
1011//===----------------------------------------------------------------------===//
1012// Comparison Instructions...
1013//
1014
1015defm t2CMP : T2I_cmp_is<"cmp",
1016 BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
1017defm t2CMPz : T2I_cmp_is<"cmp",
1018 BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
1019
1020defm t2CMN : T2I_cmp_is<"cmn",
1021 BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
1022defm t2CMNz : T2I_cmp_is<"cmn",
1023 BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
1024
1025def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
1026 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
1027
1028def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
1029 (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
1030
1031defm t2TST : T2I_cmp_is<"tst",
1032 BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
1033defm t2TEQ : T2I_cmp_is<"teq",
1034 BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
1035
1036// A8.6.27 CBNZ, CBZ - Compare and branch on (non)zero.
1037// Short range conditional branch. Looks awesome for loops. Need to figure
1038// out how to use this one.
1039
1040
1041// Conditional moves
1042// FIXME: should be able to write a pattern for ARMcmov, but can't use
1043// a two-value operand where a dag node expects two operands. :(
1044def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iCMOVr,
1045 "mov", ".w\t$dst, $true",
1046 [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
1047 RegConstraint<"$false = $dst">;
1048
1049def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true),
1050 IIC_iCMOVi, "mov", ".w\t$dst, $true",
1051[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
1052 RegConstraint<"$false = $dst">;
1053
1054def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
1055 IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
1056 RegConstraint<"$false = $dst">;
1057def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
1058 IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
1059 RegConstraint<"$false = $dst">;
1060def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
1061 IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
1062 RegConstraint<"$false = $dst">;
1063def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
1064 IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
1065 RegConstraint<"$false = $dst">;
1066
1067//===----------------------------------------------------------------------===//
1068// Atomic operations intrinsics
1069//
1070
1071// memory barriers protect the atomic sequences
1072let hasSideEffects = 1 in {
1073def t2Int_MemBarrierV7 : AInoP<(outs), (ins),
1074 Pseudo, NoItinerary,
1075 "dmb", "",
1076 [(ARMMemBarrierV7)]>,
1077 Requires<[IsThumb2]> {
1078 // FIXME: add support for options other than a full system DMB
1079}
1080
1081def t2Int_SyncBarrierV7 : AInoP<(outs), (ins),
1082 Pseudo, NoItinerary,
1083 "dsb", "",
1084 [(ARMSyncBarrierV7)]>,
1085 Requires<[IsThumb2]> {
1086 // FIXME: add support for options other than a full system DSB
1087}
1088}
1089
1090let mayLoad = 1 in {
1091def t2LDREXB : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1092 Size4Bytes, NoItinerary,
1093 "ldrexb", "\t$dest, [$ptr]", "",
1094 []>;
1095def t2LDREXH : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1096 Size4Bytes, NoItinerary,
1097 "ldrexh", "\t$dest, [$ptr]", "",
1098 []>;
1099def t2LDREX : Thumb2I<(outs GPR:$dest), (ins GPR:$ptr), AddrModeNone,
1100 Size4Bytes, NoItinerary,
1101 "ldrex", "\t$dest, [$ptr]", "",
1102 []>;
1103def t2LDREXD : Thumb2I<(outs GPR:$dest, GPR:$dest2), (ins GPR:$ptr),
1104 AddrModeNone, Size4Bytes, NoItinerary,
1105 "ldrexd", "\t$dest, $dest2, [$ptr]", "",
1106 []>;
1107}
1108
1109let mayStore = 1 in {
1110def t2STREXB : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1111 AddrModeNone, Size4Bytes, NoItinerary,
1112 "strexb", "\t$success, $src, [$ptr]", "",
1113 []>;
1114def t2STREXH : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1115 AddrModeNone, Size4Bytes, NoItinerary,
1116 "strexh", "\t$success, $src, [$ptr]", "",
1117 []>;
1118def t2STREX : Thumb2I<(outs GPR:$success), (ins GPR:$src, GPR:$ptr),
1119 AddrModeNone, Size4Bytes, NoItinerary,
1120 "strex", "\t$success, $src, [$ptr]", "",
1121 []>;
1122def t2STREXD : Thumb2I<(outs GPR:$success),
1123 (ins GPR:$src, GPR:$src2, GPR:$ptr),
1124 AddrModeNone, Size4Bytes, NoItinerary,
1125 "strexd", "\t$success, $src, $src2, [$ptr]", "",
1126 []>;
1127}
1128
1129//===----------------------------------------------------------------------===//
1130// TLS Instructions
1131//
1132
1133// __aeabi_read_tp preserves the registers r1-r3.
1134let isCall = 1,
1135 Defs = [R0, R12, LR, CPSR] in {
1136 def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
1137 "bl\t__aeabi_read_tp",
1138 [(set R0, ARMthread_pointer)]>;
1139}
1140
1141//===----------------------------------------------------------------------===//
1142// SJLJ Exception handling intrinsics
1143// eh_sjlj_setjmp() is an instruction sequence to store the return
1144// address and save #0 in R0 for the non-longjmp case.
1145// Since by its nature we may be coming from some other function to get
1146// here, and we're using the stack frame for the containing function to

--- 31 unchanged lines hidden (view full) ---

1178// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
1179// operand list.
1180// FIXME: Should pc be an implicit operand like PICADD, etc?
1181let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
1182 hasExtraDefRegAllocReq = 1 in
1183 def t2LDM_RET : T2XI<(outs),
1184 (ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
1185 IIC_Br, "ldm${addr:submode}${p}${addr:wide}\t$addr, $wb",
1186 []>;
1187
1188let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
1189let isPredicable = 1 in
1190def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
1191 "b.w\t$target",
1192 [(br bb:$target)]>;
1193
1194let isNotDuplicable = 1, isIndirectBranch = 1 in {
1195def t2BR_JT :
1196 T2JTI<(outs),
1197 (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
1198 IIC_Br, "mov\tpc, $target\n$jt",
1199 [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
1200
1201// FIXME: Add a non-pc based case that can be predicated.
1202def t2TBB :
1203 T2JTI<(outs),
1204 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
1205 IIC_Br, "tbb\t$index\n$jt", []>;
1206
1207def t2TBH :
1208 T2JTI<(outs),
1209 (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
1210 IIC_Br, "tbh\t$index\n$jt", []>;
1211} // isNotDuplicable, isIndirectBranch
1212
1213} // isBranch, isTerminator, isBarrier
1214
1215// FIXME: should be able to write a pattern for ARMBrcond, but can't use
1216// a two-value operand where a dag node expects two operands. :(
1217let isBranch = 1, isTerminator = 1 in
1218def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
1219 "b", ".w\t$target",
1220 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
1221
1222
1223// IT block
1224def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
1225 AddrModeNone, Size2Bytes, IIC_iALUx,
1226 "it$mask\t$cc", "", []>;
1227
1228//===----------------------------------------------------------------------===//
1229// Non-Instruction Patterns
1230//
1231
1232// Two piece so_imms.
1233def : T2Pat<(or GPR:$LHS, t2_so_imm2part:$RHS),
1234 (t2ORRri (t2ORRri GPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),

--- 38 unchanged lines hidden ---