~ubuntu-branches/ubuntu/trusty/llvm-toolchain-snapshot/trusty-201310232150

« back to all changes in this revision

Viewing changes to lib/Target/Hexagon/HexagonInstrInfoV4.td

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-27 15:01:57 UTC
  • mfrom: (0.10.1) (0.9.1) (0.8.1) (0.7.1) (0.6.1) (0.5.2)
  • Revision ID: package-import@ubuntu.com-20130527150157-tdkrsjpuvht7v0qx
Tags: 1:3.4~svn182733-1~exp1
* New snapshot release (3.4 release)
* Add a symlink of libLLVM-3.4.so.1 to usr/lib/llvm-3.4/lib/libLLVM-3.4.so
    to fix make the llvm-config-3.4 --libdir work (Closes: #708677)
  * Various packages rename to allow co installations:
    * libclang1 => libclang1-3.4
    * libclang1-dbg => libclang1-3.4-dbg
    * libclang-dev => libclang-3.4-dev
    * libclang-common-dev => libclang-common-3.4-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
209
209
//===----------------------------------------------------------------------===//
210
210
// LD +
211
211
//===----------------------------------------------------------------------===//
212
 
//
213
 
// These absolute set addressing mode instructions accept immediate as
214
 
// an operand. We have duplicated these patterns to take global address.
215
 
 
216
 
let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
217
 
validSubTargets = HasV4SubT in {
218
 
def LDrid_abs_setimm_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
219
 
            (ins u0AlwaysExt:$addr),
220
 
            "$dst1 = memd($dst2=##$addr)",
221
 
            []>,
222
 
            Requires<[HasV4T]>;
223
 
 
224
 
// Rd=memb(Re=#U6)
225
 
def LDrib_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
226
 
            (ins u0AlwaysExt:$addr),
227
 
            "$dst1 = memb($dst2=##$addr)",
228
 
            []>,
229
 
            Requires<[HasV4T]>;
230
 
 
231
 
// Rd=memh(Re=#U6)
232
 
def LDrih_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
233
 
            (ins u0AlwaysExt:$addr),
234
 
            "$dst1 = memh($dst2=##$addr)",
235
 
            []>,
236
 
            Requires<[HasV4T]>;
237
 
 
238
 
// Rd=memub(Re=#U6)
239
 
def LDriub_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
240
 
            (ins u0AlwaysExt:$addr),
241
 
            "$dst1 = memub($dst2=##$addr)",
242
 
            []>,
243
 
            Requires<[HasV4T]>;
244
 
 
245
 
// Rd=memuh(Re=#U6)
246
 
def LDriuh_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
247
 
            (ins u0AlwaysExt:$addr),
248
 
            "$dst1 = memuh($dst2=##$addr)",
249
 
            []>,
250
 
            Requires<[HasV4T]>;
251
 
 
252
 
// Rd=memw(Re=#U6)
253
 
def LDriw_abs_setimm_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
254
 
            (ins u0AlwaysExt:$addr),
255
 
            "$dst1 = memw($dst2=##$addr)",
256
 
            []>,
257
 
            Requires<[HasV4T]>;
258
 
}
259
 
 
260
 
// Following patterns are defined for absolute set addressing mode
261
 
// instruction which take global address as operand.
262
 
let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
263
 
validSubTargets = HasV4SubT in {
264
 
def LDrid_abs_set_V4 : LDInst2<(outs DoubleRegs:$dst1, IntRegs:$dst2),
265
 
            (ins globaladdressExt:$addr),
266
 
            "$dst1 = memd($dst2=##$addr)",
267
 
            []>,
268
 
            Requires<[HasV4T]>;
269
 
 
270
 
// Rd=memb(Re=#U6)
271
 
def LDrib_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
272
 
            (ins globaladdressExt:$addr),
273
 
            "$dst1 = memb($dst2=##$addr)",
274
 
            []>,
275
 
            Requires<[HasV4T]>;
276
 
 
277
 
// Rd=memh(Re=#U6)
278
 
def LDrih_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
279
 
            (ins globaladdressExt:$addr),
280
 
            "$dst1 = memh($dst2=##$addr)",
281
 
            []>,
282
 
            Requires<[HasV4T]>;
283
 
 
284
 
// Rd=memub(Re=#U6)
285
 
def LDriub_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
286
 
            (ins globaladdressExt:$addr),
287
 
            "$dst1 = memub($dst2=##$addr)",
288
 
            []>,
289
 
            Requires<[HasV4T]>;
290
 
 
291
 
// Rd=memuh(Re=#U6)
292
 
def LDriuh_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
293
 
            (ins globaladdressExt:$addr),
294
 
            "$dst1 = memuh($dst2=##$addr)",
295
 
            []>,
296
 
            Requires<[HasV4T]>;
297
 
 
298
 
// Rd=memw(Re=#U6)
299
 
def LDriw_abs_set_V4 : LDInst2<(outs IntRegs:$dst1, IntRegs:$dst2),
300
 
            (ins globaladdressExt:$addr),
301
 
            "$dst1 = memw($dst2=##$addr)",
302
 
            []>,
303
 
            Requires<[HasV4T]>;
304
 
}
 
212
//===----------------------------------------------------------------------===//
 
213
// Template class for load instructions with Absolute set addressing mode.
 
214
//===----------------------------------------------------------------------===//
 
215
let isExtended = 1, opExtendable = 2, neverHasSideEffects = 1,
 
216
validSubTargets = HasV4SubT, addrMode = AbsoluteSet in
 
217
class T_LD_abs_set<string mnemonic, RegisterClass RC>:
 
218
            LDInst2<(outs RC:$dst1, IntRegs:$dst2),
 
219
            (ins u0AlwaysExt:$addr),
 
220
            "$dst1 = "#mnemonic#"($dst2=##$addr)",
 
221
            []>,
 
222
            Requires<[HasV4T]>;
 
223
 
 
224
def LDrid_abs_set_V4  : T_LD_abs_set <"memd", DoubleRegs>;
 
225
def LDrib_abs_set_V4  : T_LD_abs_set <"memb", IntRegs>;
 
226
def LDriub_abs_set_V4 : T_LD_abs_set <"memub", IntRegs>;
 
227
def LDrih_abs_set_V4  : T_LD_abs_set <"memh", IntRegs>;
 
228
def LDriw_abs_set_V4  : T_LD_abs_set <"memw", IntRegs>;
 
229
def LDriuh_abs_set_V4 : T_LD_abs_set <"memuh", IntRegs>;
 
230
 
305
231
 
306
232
// multiclass for load instructions with base + register offset
307
233
// addressing mode
340
266
}
341
267
 
342
268
let addrMode = BaseRegOffset in {
343
 
  defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>, AddrModeRel;
344
 
  defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>, AddrModeRel;
345
 
  defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel;
346
 
  defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>, AddrModeRel;
347
 
  defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel;
348
 
  defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>, AddrModeRel;
 
269
  let accessSize = ByteAccess in {
 
270
    defm LDrib_indexed_shl: ld_idxd_shl<"memb", "LDrib", IntRegs>,
 
271
                                        AddrModeRel;
 
272
    defm LDriub_indexed_shl: ld_idxd_shl<"memub", "LDriub", IntRegs>,
 
273
                                        AddrModeRel;
 
274
  }
 
275
  let accessSize = HalfWordAccess in {
 
276
    defm LDrih_indexed_shl: ld_idxd_shl<"memh", "LDrih", IntRegs>, AddrModeRel;
 
277
    defm LDriuh_indexed_shl: ld_idxd_shl<"memuh", "LDriuh", IntRegs>,
 
278
                             AddrModeRel;
 
279
  }
 
280
  let accessSize = WordAccess in
 
281
     defm LDriw_indexed_shl: ld_idxd_shl<"memw", "LDriw", IntRegs>, AddrModeRel;
 
282
 
 
283
  let accessSize = DoubleWordAccess in
 
284
    defm LDrid_indexed_shl: ld_idxd_shl<"memd", "LDrid", DoubleRegs>,
 
285
                             AddrModeRel;
349
286
}
350
287
 
351
288
// 'def pats' for load instructions with base + register offset and non-zero
527
464
// ST +
528
465
//===----------------------------------------------------------------------===//
529
466
///
530
 
/// Assumptions::: ****** DO NOT IGNORE ********
531
 
/// 1. Make sure that in post increment store, the zero'th operand is always the
532
 
///    post increment operand.
533
 
/// 2. Make sure that the store value operand(Rt/Rtt) in a store is always the
534
 
///    last operand.
535
 
///
536
 
 
537
 
// memd(Re=#U)=Rtt
538
 
let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
539
 
def STrid_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
540
 
            (ins DoubleRegs:$src1, u0AlwaysExt:$src2),
541
 
            "memd($dst1=##$src2) = $src1",
542
 
            []>,
543
 
            Requires<[HasV4T]>;
544
 
 
545
 
// memb(Re=#U)=Rs
546
 
def STrib_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
547
 
            (ins IntRegs:$src1, u0AlwaysExt:$src2),
548
 
            "memb($dst1=##$src2) = $src1",
549
 
            []>,
550
 
            Requires<[HasV4T]>;
551
 
 
552
 
// memh(Re=#U)=Rs
553
 
def STrih_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
554
 
            (ins IntRegs:$src1, u0AlwaysExt:$src2),
555
 
            "memh($dst1=##$src2) = $src1",
556
 
            []>,
557
 
            Requires<[HasV4T]>;
558
 
 
559
 
// memw(Re=#U)=Rs
560
 
def STriw_abs_setimm_V4 : STInst2<(outs IntRegs:$dst1),
561
 
            (ins IntRegs:$src1, u0AlwaysExt:$src2),
562
 
            "memw($dst1=##$src2) = $src1",
563
 
            []>,
564
 
            Requires<[HasV4T]>;
565
 
}
566
 
 
567
 
// memd(Re=#U)=Rtt
568
 
let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in {
569
 
def STrid_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
570
 
            (ins DoubleRegs:$src1, globaladdressExt:$src2),
571
 
            "memd($dst1=##$src2) = $src1",
572
 
            []>,
573
 
            Requires<[HasV4T]>;
574
 
 
575
 
// memb(Re=#U)=Rs
576
 
def STrib_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
577
 
            (ins IntRegs:$src1, globaladdressExt:$src2),
578
 
            "memb($dst1=##$src2) = $src1",
579
 
            []>,
580
 
            Requires<[HasV4T]>;
581
 
 
582
 
// memh(Re=#U)=Rs
583
 
def STrih_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
584
 
            (ins IntRegs:$src1, globaladdressExt:$src2),
585
 
            "memh($dst1=##$src2) = $src1",
586
 
            []>,
587
 
            Requires<[HasV4T]>;
588
 
 
589
 
// memw(Re=#U)=Rs
590
 
def STriw_abs_set_V4 : STInst2<(outs IntRegs:$dst1),
591
 
            (ins IntRegs:$src1, globaladdressExt:$src2),
592
 
            "memw($dst1=##$src2) = $src1",
593
 
            []>,
594
 
            Requires<[HasV4T]>;
595
 
}
596
 
 
 
467
//===----------------------------------------------------------------------===//
 
468
// Template class for store instructions with Absolute set addressing mode.
 
469
//===----------------------------------------------------------------------===//
 
470
let isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT,
 
471
addrMode = AbsoluteSet in
 
472
class T_ST_abs_set<string mnemonic, RegisterClass RC>:
 
473
            STInst2<(outs IntRegs:$dst1),
 
474
            (ins RC:$src1, u0AlwaysExt:$src2),
 
475
            mnemonic#"($dst1=##$src2) = $src1",
 
476
            []>,
 
477
            Requires<[HasV4T]>;
 
478
 
 
479
def STrid_abs_set_V4 : T_ST_abs_set <"memd", DoubleRegs>;
 
480
def STrib_abs_set_V4 : T_ST_abs_set <"memb", IntRegs>;
 
481
def STrih_abs_set_V4 : T_ST_abs_set <"memh", IntRegs>;
 
482
def STriw_abs_set_V4 : T_ST_abs_set <"memw", IntRegs>;
 
483
 
 
484
//===----------------------------------------------------------------------===//
597
485
// multiclass for store instructions with base + register offset addressing
598
486
// mode
 
487
//===----------------------------------------------------------------------===//
599
488
multiclass ST_Idxd_shl_Pbase<string mnemonic, RegisterClass RC, bit isNot,
600
489
                             bit isPredNew> {
601
490
  let isPredicatedNew = isPredNew in
674
563
 
675
564
let addrMode = BaseRegOffset, neverHasSideEffects = 1,
676
565
validSubTargets = HasV4SubT in {
677
 
  defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
678
 
                          ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
679
 
 
680
 
  defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
681
 
                          ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
682
 
 
683
 
  defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
684
 
                          ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
685
 
 
686
 
  let isNVStorable = 0 in
687
 
  defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
 
566
  let accessSize = ByteAccess in
 
567
    defm STrib_indexed_shl: ST_Idxd_shl<"memb", "STrib", IntRegs>,
 
568
                            ST_Idxd_shl_nv<"memb", "STrib", IntRegs>, AddrModeRel;
 
569
 
 
570
  let accessSize = HalfWordAccess in
 
571
    defm STrih_indexed_shl: ST_Idxd_shl<"memh", "STrih", IntRegs>,
 
572
                            ST_Idxd_shl_nv<"memh", "STrih", IntRegs>, AddrModeRel;
 
573
 
 
574
  let accessSize = WordAccess in
 
575
    defm STriw_indexed_shl: ST_Idxd_shl<"memw", "STriw", IntRegs>,
 
576
                            ST_Idxd_shl_nv<"memw", "STriw", IntRegs>, AddrModeRel;
 
577
 
 
578
  let isNVStorable = 0, accessSize = DoubleWordAccess in
 
579
    defm STrid_indexed_shl: ST_Idxd_shl<"memd", "STrid", DoubleRegs>, AddrModeRel;
688
580
}
689
581
 
690
582
let Predicates = [HasV4T], AddedComplexity = 10 in {
711
603
                                u2ImmPred:$src3, DoubleRegs:$src4)>;
712
604
}
713
605
 
714
 
// memd(Ru<<#u2+#U6)=Rtt
715
 
let isExtended = 1, opExtendable = 2, AddedComplexity = 10,
716
 
validSubTargets = HasV4SubT in
717
 
def STrid_shl_V4 : STInst<(outs),
718
 
            (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, DoubleRegs:$src4),
719
 
            "memd($src1<<#$src2+#$src3) = $src4",
720
 
            [(store (i64 DoubleRegs:$src4),
 
606
let isExtended = 1, opExtendable = 2 in
 
607
class T_ST_LongOff <string mnemonic, PatFrag stOp, RegisterClass RC, ValueType VT> :
 
608
            STInst<(outs),
 
609
            (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, RC:$src4),
 
610
            mnemonic#"($src1<<#$src2+##$src3) = $src4",
 
611
            [(stOp (VT RC:$src4),
721
612
                    (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
722
613
                         u0AlwaysExtPred:$src3))]>,
723
614
            Requires<[HasV4T]>;
724
615
 
 
616
let isExtended = 1, opExtendable = 2, mayStore = 1, isNVStore = 1 in
 
617
class T_ST_LongOff_nv <string mnemonic> :
 
618
            NVInst_V4<(outs),
 
619
            (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
 
620
            mnemonic#"($src1<<#$src2+##$src3) = $src4.new",
 
621
            []>,
 
622
            Requires<[HasV4T]>;
 
623
 
 
624
multiclass ST_LongOff <string mnemonic, string BaseOp, PatFrag stOp> {
 
625
  let  BaseOpcode = BaseOp#"_shl" in {
 
626
    let isNVStorable = 1 in
 
627
    def NAME#_V4 : T_ST_LongOff<mnemonic, stOp, IntRegs, i32>;
 
628
 
 
629
    def NAME#_nv_V4 : T_ST_LongOff_nv<mnemonic>;
 
630
  }
 
631
}
 
632
 
 
633
let AddedComplexity = 10, validSubTargets = HasV4SubT in {
 
634
  def STrid_shl_V4 : T_ST_LongOff<"memd", store, DoubleRegs, i64>;
 
635
  defm STrib_shl   : ST_LongOff <"memb", "STrib", truncstorei8>, NewValueRel;
 
636
  defm STrih_shl   : ST_LongOff <"memh", "Strih", truncstorei16>, NewValueRel;
 
637
  defm STriw_shl   : ST_LongOff <"memw", "STriw", store>, NewValueRel;
 
638
}
 
639
 
 
640
let AddedComplexity = 40 in
 
641
multiclass T_ST_LOff_Pats <InstHexagon I, RegisterClass RC, ValueType VT,
 
642
                           PatFrag stOp> {
 
643
 def : Pat<(stOp (VT RC:$src4),
 
644
           (add (shl IntRegs:$src1, u2ImmPred:$src2),
 
645
               (NumUsesBelowThresCONST32 tglobaladdr:$src3))),
 
646
           (I IntRegs:$src1, u2ImmPred:$src2, tglobaladdr:$src3, RC:$src4)>;
 
647
 
 
648
 def : Pat<(stOp (VT RC:$src4),
 
649
           (add IntRegs:$src1,
 
650
               (NumUsesBelowThresCONST32 tglobaladdr:$src3))),
 
651
           (I IntRegs:$src1, 0, tglobaladdr:$src3, RC:$src4)>;
 
652
}
 
653
 
 
654
defm : T_ST_LOff_Pats<STrid_shl_V4, DoubleRegs, i64, store>;
 
655
defm : T_ST_LOff_Pats<STriw_shl_V4, IntRegs, i32, store>;
 
656
defm : T_ST_LOff_Pats<STrib_shl_V4, IntRegs, i32, truncstorei8>;
 
657
defm : T_ST_LOff_Pats<STrih_shl_V4, IntRegs, i32, truncstorei16>;
 
658
 
725
659
// memd(Rx++#s4:3)=Rtt
726
660
// memd(Rx++#s4:3:circ(Mu))=Rtt
727
661
// memd(Rx++I:circ(Mu))=Rtt
776
710
}
777
711
 
778
712
let addrMode = BaseImmOffset, InputType = "imm",
779
 
    validSubTargets = HasV4SubT in {
780
 
  defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
781
 
  defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
782
 
  defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
 
713
validSubTargets = HasV4SubT in {
 
714
  let accessSize = ByteAccess in
 
715
    defm STrib_imm : ST_Imm<"memb", "STrib", u6_0Imm>, ImmRegRel, PredNewRel;
 
716
 
 
717
  let accessSize = HalfWordAccess in
 
718
    defm STrih_imm : ST_Imm<"memh", "STrih", u6_1Imm>, ImmRegRel, PredNewRel;
 
719
 
 
720
  let accessSize = WordAccess in
 
721
    defm STriw_imm : ST_Imm<"memw", "STriw", u6_2Imm>, ImmRegRel, PredNewRel;
783
722
}
784
723
 
785
724
let Predicates = [HasV4T], AddedComplexity = 10 in {
799
738
           (STrib_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
800
739
           Requires<[HasV4T]>;
801
740
 
802
 
// memb(Ru<<#u2+#U6)=Rt
803
 
let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
804
 
validSubTargets = HasV4SubT in
805
 
def STrib_shl_V4 : STInst<(outs),
806
 
            (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
807
 
            "memb($src1<<#$src2+#$src3) = $src4",
808
 
            [(truncstorei8 (i32 IntRegs:$src4),
809
 
                           (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
810
 
                                u0AlwaysExtPred:$src3))]>,
811
 
            Requires<[HasV4T]>;
812
 
 
813
741
// memb(Rx++#s4:0:circ(Mu))=Rt
814
742
// memb(Rx++I:circ(Mu))=Rt
815
743
// memb(Rx++Mu)=Rt
830
758
// TODO: needs to be implemented.
831
759
 
832
760
// memh(Ru<<#u2+#U6)=Rt.H
833
 
// memh(Ru<<#u2+#U6)=Rt
834
 
let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
835
 
validSubTargets = HasV4SubT in
836
 
def STrih_shl_V4 : STInst<(outs),
837
 
            (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
838
 
            "memh($src1<<#$src2+#$src3) = $src4",
839
 
            [(truncstorei16 (i32 IntRegs:$src4),
840
 
                            (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
841
 
                                 u0AlwaysExtPred:$src3))]>,
842
 
            Requires<[HasV4T]>;
843
 
 
844
761
// memh(Rx++#s4:1:circ(Mu))=Rt.H
845
762
// memh(Rx++#s4:1:circ(Mu))=Rt
846
763
// memh(Rx++I:circ(Mu))=Rt.H
877
794
           (STriw_imm_V4 IntRegs:$src1, 0, s8ExtPred:$src2)>,
878
795
           Requires<[HasV4T]>;
879
796
 
880
 
// memw(Ru<<#u2+#U6)=Rt
881
 
let isExtended = 1, opExtendable = 2, AddedComplexity = 10, isNVStorable = 1,
882
 
validSubTargets = HasV4SubT in
883
 
def STriw_shl_V4 : STInst<(outs),
884
 
            (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
885
 
            "memw($src1<<#$src2+#$src3) = $src4",
886
 
            [(store (i32 IntRegs:$src4),
887
 
                    (add (shl (i32 IntRegs:$src1), u2ImmPred:$src2),
888
 
                              u0AlwaysExtPred:$src3))]>,
889
 
            Requires<[HasV4T]>;
890
 
 
891
797
// memw(Rx++#s4:2)=Rt
892
798
// memw(Rx++#s4:2:circ(Mu))=Rt
893
799
// memw(Rx++I:circ(Mu))=Rt
948
854
}
949
855
 
950
856
let addrMode = BaseImmOffset, validSubTargets = HasV4SubT in {
951
 
  defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
952
 
                                 u6_0Ext, 11, 6>, AddrModeRel;
953
 
  defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
954
 
                                 u6_1Ext, 12, 7>, AddrModeRel;
955
 
  defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
956
 
                                 u6_2Ext, 13, 8>, AddrModeRel;
 
857
  let accessSize = ByteAccess in
 
858
    defm STrib_indexed: ST_Idxd_nv<"memb", "STrib", IntRegs, s11_0Ext,
 
859
                                   u6_0Ext, 11, 6>, AddrModeRel;
 
860
 
 
861
  let accessSize = HalfWordAccess in
 
862
    defm STrih_indexed: ST_Idxd_nv<"memh", "STrih", IntRegs, s11_1Ext,
 
863
                                   u6_1Ext, 12, 7>, AddrModeRel;
 
864
 
 
865
  let accessSize = WordAccess in
 
866
    defm STriw_indexed: ST_Idxd_nv<"memw", "STriw", IntRegs, s11_2Ext,
 
867
                                   u6_2Ext, 13, 8>, AddrModeRel;
957
868
}
958
869
 
959
870
// multiclass for new-value store instructions with base + immediate offset.
1001
912
 
1002
913
let addrMode = BaseImmOffset, isMEMri = "true", validSubTargets = HasV4SubT,
1003
914
mayStore = 1 in {
1004
 
  defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
1005
 
  defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
1006
 
  defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
 
915
  let accessSize = ByteAccess in
 
916
    defm STrib: ST_MEMri_nv<"memb", "STrib", IntRegs, 11, 6>, AddrModeRel;
 
917
 
 
918
  let accessSize = HalfWordAccess in
 
919
    defm STrih: ST_MEMri_nv<"memh", "STrih", IntRegs, 12, 7>, AddrModeRel;
 
920
 
 
921
  let accessSize = WordAccess in
 
922
    defm STriw: ST_MEMri_nv<"memw", "STriw", IntRegs, 13, 8>, AddrModeRel;
1007
923
}
1008
924
 
1009
 
// memb(Ru<<#u2+#U6)=Nt.new
1010
 
let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1011
 
isNVStore = 1, validSubTargets = HasV4SubT in
1012
 
def STrib_shl_nv_V4 : NVInst_V4<(outs),
1013
 
            (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1014
 
            "memb($src1<<#$src2+#$src3) = $src4.new",
1015
 
            []>,
1016
 
            Requires<[HasV4T]>;
1017
 
 
1018
925
//===----------------------------------------------------------------------===//
1019
926
// Post increment store
1020
927
// mem[bhwd](Rx++#s4:[0123])=Nt.new
1062
969
  }
1063
970
}
1064
971
 
1065
 
let validSubTargets = HasV4SubT in {
 
972
let addrMode = PostInc, validSubTargets = HasV4SubT in {
1066
973
defm POST_STbri: ST_PostInc_nv <"memb", "STrib", IntRegs, s4_0Imm>, AddrModeRel;
1067
974
defm POST_SThri: ST_PostInc_nv <"memh", "STrih", IntRegs, s4_1Imm>, AddrModeRel;
1068
975
defm POST_STwri: ST_PostInc_nv <"memw", "STriw", IntRegs, s4_2Imm>, AddrModeRel;
1072
979
// memb(Rx++I:circ(Mu))=Nt.new
1073
980
// memb(Rx++Mu)=Nt.new
1074
981
// memb(Rx++Mu:brev)=Nt.new
1075
 
// memh(Ru<<#u2+#U6)=Nt.new
1076
 
let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1077
 
isNVStore = 1, validSubTargets = HasV4SubT in
1078
 
def STrih_shl_nv_V4 : NVInst_V4<(outs),
1079
 
            (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1080
 
            "memh($src1<<#$src2+#$src3) = $src4.new",
1081
 
            []>,
1082
 
            Requires<[HasV4T]>;
1083
 
 
1084
982
// memh(Rx++#s4:1:circ(Mu))=Nt.new
1085
983
// memh(Rx++I:circ(Mu))=Nt.new
1086
984
// memh(Rx++Mu)=Nt.new
1087
985
// memh(Rx++Mu:brev)=Nt.new
1088
986
 
1089
 
// memw(Ru<<#u2+#U6)=Nt.new
1090
 
let isExtended = 1, opExtendable = 2, mayStore = 1, AddedComplexity = 10,
1091
 
isNVStore = 1, validSubTargets = HasV4SubT in
1092
 
def STriw_shl_nv_V4 : NVInst_V4<(outs),
1093
 
            (ins IntRegs:$src1, u2Imm:$src2, u0AlwaysExt:$src3, IntRegs:$src4),
1094
 
            "memw($src1<<#$src2+#$src3) = $src4.new",
1095
 
            []>,
1096
 
            Requires<[HasV4T]>;
1097
 
 
1098
987
// memw(Rx++#s4:2:circ(Mu))=Nt.new
1099
988
// memw(Rx++I:circ(Mu))=Nt.new
1100
989
// memw(Rx++Mu)=Nt.new
1108
997
// NV/J +
1109
998
//===----------------------------------------------------------------------===//
1110
999
 
1111
 
multiclass NVJ_type_basic_reg<string NotStr, string OpcStr, string TakenStr> {
1112
 
  def _ie_nv_V4 : NVInst_V4<(outs),
1113
 
            (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1114
 
            !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1115
 
            !strconcat("($src1.new, $src2)) jump:",
1116
 
            !strconcat(TakenStr, " $offset"))))),
1117
 
            []>,
1118
 
            Requires<[HasV4T]>;
1119
 
 
1120
 
  def _nv_V4 : NVInst_V4<(outs),
1121
 
            (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1122
 
            !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1123
 
            !strconcat("($src1.new, $src2)) jump:",
1124
 
            !strconcat(TakenStr, " $offset"))))),
1125
 
            []>,
1126
 
            Requires<[HasV4T]>;
1127
 
}
1128
 
 
1129
 
multiclass NVJ_type_basic_2ndDotNew<string NotStr, string OpcStr,
1130
 
                                                   string TakenStr> {
1131
 
  def _ie_nv_V4 : NVInst_V4<(outs),
1132
 
            (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1133
 
            !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1134
 
            !strconcat("($src1, $src2.new)) jump:",
1135
 
            !strconcat(TakenStr, " $offset"))))),
1136
 
            []>,
1137
 
            Requires<[HasV4T]>;
1138
 
 
1139
 
  def _nv_V4 : NVInst_V4<(outs),
1140
 
            (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
1141
 
            !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1142
 
            !strconcat("($src1, $src2.new)) jump:",
1143
 
            !strconcat(TakenStr, " $offset"))))),
1144
 
            []>,
1145
 
            Requires<[HasV4T]>;
1146
 
}
1147
 
 
1148
 
multiclass NVJ_type_basic_imm<string NotStr, string OpcStr, string TakenStr> {
1149
 
  def _ie_nv_V4 : NVInst_V4<(outs),
1150
 
            (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1151
 
            !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1152
 
            !strconcat("($src1.new, #$src2)) jump:",
1153
 
            !strconcat(TakenStr, " $offset"))))),
1154
 
            []>,
1155
 
            Requires<[HasV4T]>;
1156
 
 
1157
 
  def _nv_V4 : NVInst_V4<(outs),
1158
 
            (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
1159
 
            !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1160
 
            !strconcat("($src1.new, #$src2)) jump:",
1161
 
            !strconcat(TakenStr, " $offset"))))),
1162
 
            []>,
1163
 
            Requires<[HasV4T]>;
1164
 
}
1165
 
 
1166
 
multiclass NVJ_type_basic_neg<string NotStr, string OpcStr, string TakenStr> {
1167
 
  def _ie_nv_V4 : NVInst_V4<(outs),
1168
 
            (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
1169
 
            !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1170
 
            !strconcat("($src1.new, #$src2)) jump:",
1171
 
            !strconcat(TakenStr, " $offset"))))),
1172
 
            []>,
1173
 
            Requires<[HasV4T]>;
1174
 
 
1175
 
  def _nv_V4 : NVInst_V4<(outs),
1176
 
            (ins IntRegs:$src1, nOneImm:$src2, brtarget:$offset),
1177
 
            !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1178
 
            !strconcat("($src1.new, #$src2)) jump:",
1179
 
            !strconcat(TakenStr, " $offset"))))),
1180
 
            []>,
1181
 
            Requires<[HasV4T]>;
1182
 
}
1183
 
 
1184
 
multiclass NVJ_type_basic_tstbit<string NotStr, string OpcStr,
1185
 
                                                string TakenStr> {
1186
 
  def _ie_nv_V4 : NVInst_V4<(outs),
1187
 
            (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset),
1188
 
            !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1189
 
            !strconcat("($src1.new, #$src2)) jump:",
1190
 
            !strconcat(TakenStr, " $offset"))))),
1191
 
            []>,
1192
 
            Requires<[HasV4T]>;
1193
 
 
1194
 
  def _nv_V4 : NVInst_V4<(outs),
1195
 
            (ins IntRegs:$src1, u1Imm:$src2, brtarget:$offset),
1196
 
            !strconcat("if (", !strconcat(NotStr, !strconcat(OpcStr,
1197
 
            !strconcat("($src1.new, #$src2)) jump:",
1198
 
            !strconcat(TakenStr, " $offset"))))),
1199
 
            []>,
1200
 
            Requires<[HasV4T]>;
1201
 
}
1202
 
 
1203
 
// Multiclass for regular dot new of Ist operand register.
1204
 
multiclass NVJ_type_br_pred_reg<string NotStr, string OpcStr> {
1205
 
  defm Pt  : NVJ_type_basic_reg<NotStr, OpcStr, "t">;
1206
 
  defm Pnt : NVJ_type_basic_reg<NotStr, OpcStr, "nt">;
1207
 
}
1208
 
 
1209
 
// Multiclass for dot new of 2nd operand register.
1210
 
multiclass NVJ_type_br_pred_2ndDotNew<string NotStr, string OpcStr> {
1211
 
  defm Pt  : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "t">;
1212
 
  defm Pnt : NVJ_type_basic_2ndDotNew<NotStr, OpcStr, "nt">;
1213
 
}
1214
 
 
1215
 
// Multiclass for 2nd operand immediate, including -1.
1216
 
multiclass NVJ_type_br_pred_imm<string NotStr, string OpcStr> {
1217
 
  defm Pt     : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
1218
 
  defm Pnt    : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
1219
 
  defm Ptneg  : NVJ_type_basic_neg<NotStr, OpcStr, "t">;
1220
 
  defm Pntneg : NVJ_type_basic_neg<NotStr, OpcStr, "nt">;
1221
 
}
1222
 
 
1223
 
// Multiclass for 2nd operand immediate, excluding -1.
1224
 
multiclass NVJ_type_br_pred_imm_only<string NotStr, string OpcStr> {
1225
 
  defm Pt     : NVJ_type_basic_imm<NotStr, OpcStr, "t">;
1226
 
  defm Pnt    : NVJ_type_basic_imm<NotStr, OpcStr, "nt">;
1227
 
}
1228
 
 
1229
 
// Multiclass for tstbit, where 2nd operand is always #0.
1230
 
multiclass NVJ_type_br_pred_tstbit<string NotStr, string OpcStr> {
1231
 
  defm Pt     : NVJ_type_basic_tstbit<NotStr, OpcStr, "t">;
1232
 
  defm Pnt    : NVJ_type_basic_tstbit<NotStr, OpcStr, "nt">;
1233
 
}
1234
 
 
1235
 
// Multiclass for GT.
1236
 
multiclass NVJ_type_rr_ri<string OpcStr> {
1237
 
  defm rrNot   : NVJ_type_br_pred_reg<"!", OpcStr>;
1238
 
  defm rr      : NVJ_type_br_pred_reg<"",  OpcStr>;
1239
 
  defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>;
1240
 
  defm rrdn    : NVJ_type_br_pred_2ndDotNew<"",  OpcStr>;
1241
 
  defm riNot   : NVJ_type_br_pred_imm<"!", OpcStr>;
1242
 
  defm ri      : NVJ_type_br_pred_imm<"",  OpcStr>;
1243
 
}
1244
 
 
1245
 
// Multiclass for EQ.
1246
 
multiclass NVJ_type_rr_ri_no_2ndDotNew<string OpcStr> {
1247
 
  defm rrNot   : NVJ_type_br_pred_reg<"!", OpcStr>;
1248
 
  defm rr      : NVJ_type_br_pred_reg<"",  OpcStr>;
1249
 
  defm riNot   : NVJ_type_br_pred_imm<"!", OpcStr>;
1250
 
  defm ri      : NVJ_type_br_pred_imm<"",  OpcStr>;
1251
 
}
1252
 
 
1253
 
// Multiclass for GTU.
1254
 
multiclass NVJ_type_rr_ri_no_nOne<string OpcStr> {
1255
 
  defm rrNot   : NVJ_type_br_pred_reg<"!", OpcStr>;
1256
 
  defm rr      : NVJ_type_br_pred_reg<"",  OpcStr>;
1257
 
  defm rrdnNot : NVJ_type_br_pred_2ndDotNew<"!", OpcStr>;
1258
 
  defm rrdn    : NVJ_type_br_pred_2ndDotNew<"",  OpcStr>;
1259
 
  defm riNot   : NVJ_type_br_pred_imm_only<"!", OpcStr>;
1260
 
  defm ri      : NVJ_type_br_pred_imm_only<"",  OpcStr>;
1261
 
}
1262
 
 
1263
 
// Multiclass for tstbit.
1264
 
multiclass NVJ_type_r0<string OpcStr> {
1265
 
  defm r0Not : NVJ_type_br_pred_tstbit<"!", OpcStr>;
1266
 
  defm r0    : NVJ_type_br_pred_tstbit<"",  OpcStr>;
1267
 
 }
1268
 
 
1269
 
// Base Multiclass for New Value Jump.
1270
 
multiclass NVJ_type {
1271
 
  defm GT     : NVJ_type_rr_ri<"cmp.gt">;
1272
 
  defm EQ     : NVJ_type_rr_ri_no_2ndDotNew<"cmp.eq">;
1273
 
  defm GTU    : NVJ_type_rr_ri_no_nOne<"cmp.gtu">;
1274
 
  defm TSTBIT : NVJ_type_r0<"tstbit">;
1275
 
}
1276
 
 
1277
 
let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in {
1278
 
  defm JMP_ : NVJ_type;
1279
 
}
1280
 
 
1281
 
//===----------------------------------------------------------------------===//
1282
 
// NV/J -
1283
 
//===----------------------------------------------------------------------===//
 
1000
//===----------------------------------------------------------------------===//
 
1001
// multiclass/template class for the new-value compare jumps with the register
 
1002
// operands.
 
1003
//===----------------------------------------------------------------------===//
 
1004
 
 
1005
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
 
1006
class NVJrr_template<string mnemonic, bits<3> majOp, bit NvOpNum,
 
1007
                      bit isNegCond, bit isTaken>
 
1008
  : NVInst_V4<(outs),
 
1009
    (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset),
 
1010
    "if ("#!if(isNegCond, "!","")#mnemonic#
 
1011
    "($src1"#!if(!eq(NvOpNum, 0),".new, ",", ")#
 
1012
    "$src2"#!if(!eq(NvOpNum, 1),".new))","))")#" jump:"
 
1013
    #!if(isTaken, "t","nt")#" $offset",
 
1014
    []>, Requires<[HasV4T]> {
 
1015
 
 
1016
      bits<5> src1;
 
1017
      bits<5> src2;
 
1018
      bits<3> Ns;    // New-Value Operand
 
1019
      bits<5> RegOp; // Non New-Value Operand
 
1020
      bits<11> offset;
 
1021
 
 
1022
      let isBrTaken = !if(isTaken, "true", "false");
 
1023
      let isPredicatedFalse = isNegCond;
 
1024
 
 
1025
      let Ns = !if(!eq(NvOpNum, 0), src1{2-0}, src2{2-0});
 
1026
      let RegOp = !if(!eq(NvOpNum, 0), src2, src1);
 
1027
 
 
1028
      let IClass = 0b0010;
 
1029
      let Inst{26} = 0b0;
 
1030
      let Inst{25-23} = majOp;
 
1031
      let Inst{22} = isNegCond;
 
1032
      let Inst{18-16} = Ns;
 
1033
      let Inst{13} = isTaken;
 
1034
      let Inst{12-8} = RegOp;
 
1035
      let Inst{21-20} = offset{10-9};
 
1036
      let Inst{7-1} = offset{8-2};
 
1037
}
 
1038
 
 
1039
 
 
1040
multiclass NVJrr_cond<string mnemonic, bits<3> majOp, bit NvOpNum,
 
1041
                       bit isNegCond> {
 
1042
  // Branch not taken:
 
1043
  def _nt_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 0>;
 
1044
  // Branch taken:
 
1045
  def _t_V4: NVJrr_template<mnemonic, majOp, NvOpNum, isNegCond, 1>;
 
1046
}
 
1047
 
 
1048
// NvOpNum = 0 -> First Operand is a new-value Register
 
1049
// NvOpNum = 1 -> Second Operand is a new-value Register
 
1050
 
 
1051
multiclass NVJrr_base<string mnemonic, string BaseOp, bits<3> majOp,
 
1052
                       bit NvOpNum> {
 
1053
  let BaseOpcode = BaseOp#_NVJ in {
 
1054
    defm _t_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 0>; // True cond
 
1055
    defm _f_Jumpnv : NVJrr_cond<mnemonic, majOp, NvOpNum, 1>; // False cond
 
1056
  }
 
1057
}
 
1058
 
 
1059
// if ([!]cmp.eq(Ns.new,Rt)) jump:[n]t #r9:2
 
1060
// if ([!]cmp.gt(Ns.new,Rt)) jump:[n]t #r9:2
 
1061
// if ([!]cmp.gtu(Ns.new,Rt)) jump:[n]t #r9:2
 
1062
// if ([!]cmp.gt(Rt,Ns.new)) jump:[n]t #r9:2
 
1063
// if ([!]cmp.gtu(Rt,Ns.new)) jump:[n]t #r9:2
 
1064
 
 
1065
let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
 
1066
  Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
 
1067
  defm CMPEQrr  : NVJrr_base<"cmp.eq",  "CMPEQ",  0b000, 0>, PredRel;
 
1068
  defm CMPGTrr  : NVJrr_base<"cmp.gt",  "CMPGT",  0b001, 0>, PredRel;
 
1069
  defm CMPGTUrr : NVJrr_base<"cmp.gtu", "CMPGTU", 0b010, 0>, PredRel;
 
1070
  defm CMPLTrr  : NVJrr_base<"cmp.gt",  "CMPLT",  0b011, 1>, PredRel;
 
1071
  defm CMPLTUrr : NVJrr_base<"cmp.gtu", "CMPLTU", 0b100, 1>, PredRel;
 
1072
}
 
1073
 
 
1074
//===----------------------------------------------------------------------===//
 
1075
// multiclass/template class for the new-value compare jumps instruction
 
1076
// with a register and an unsigned immediate (U5) operand.
 
1077
//===----------------------------------------------------------------------===//
 
1078
 
 
1079
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 11 in
 
1080
class NVJri_template<string mnemonic, bits<3> majOp, bit isNegCond,
 
1081
                         bit isTaken>
 
1082
  : NVInst_V4<(outs),
 
1083
    (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset),
 
1084
    "if ("#!if(isNegCond, "!","")#mnemonic#"($src1.new, #$src2)) jump:"
 
1085
    #!if(isTaken, "t","nt")#" $offset",
 
1086
    []>, Requires<[HasV4T]> {
 
1087
 
 
1088
      let isPredicatedFalse = isNegCond;
 
1089
      let isBrTaken = !if(isTaken, "true", "false");
 
1090
 
 
1091
      bits<3> src1;
 
1092
      bits<5> src2;
 
1093
      bits<11> offset;
 
1094
 
 
1095
      let IClass = 0b0010;
 
1096
      let Inst{26} = 0b1;
 
1097
      let Inst{25-23} = majOp;
 
1098
      let Inst{22} = isNegCond;
 
1099
      let Inst{18-16} = src1;
 
1100
      let Inst{13} = isTaken;
 
1101
      let Inst{12-8} = src2;
 
1102
      let Inst{21-20} = offset{10-9};
 
1103
      let Inst{7-1} = offset{8-2};
 
1104
}
 
1105
 
 
1106
multiclass NVJri_cond<string mnemonic, bits<3> majOp, bit isNegCond> {
 
1107
  // Branch not taken:
 
1108
  def _nt_V4: NVJri_template<mnemonic, majOp, isNegCond, 0>;
 
1109
  // Branch taken:
 
1110
  def _t_V4: NVJri_template<mnemonic, majOp, isNegCond, 1>;
 
1111
}
 
1112
 
 
1113
multiclass NVJri_base<string mnemonic, string BaseOp, bits<3> majOp> {
 
1114
  let BaseOpcode = BaseOp#_NVJri in {
 
1115
    defm _t_Jumpnv : NVJri_cond<mnemonic, majOp, 0>; // True Cond
 
1116
    defm _f_Jumpnv : NVJri_cond<mnemonic, majOp, 1>; // False cond
 
1117
  }
 
1118
}
 
1119
 
 
1120
// if ([!]cmp.eq(Ns.new,#U5)) jump:[n]t #r9:2
 
1121
// if ([!]cmp.gt(Ns.new,#U5)) jump:[n]t #r9:2
 
1122
// if ([!]cmp.gtu(Ns.new,#U5)) jump:[n]t #r9:2
 
1123
 
 
1124
let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator = 1,
 
1125
  Defs = [PC], neverHasSideEffects = 1, validSubTargets = HasV4SubT in {
 
1126
  defm CMPEQri  : NVJri_base<"cmp.eq", "CMPEQ", 0b000>, PredRel;
 
1127
  defm CMPGTri  : NVJri_base<"cmp.gt", "CMPGT", 0b001>, PredRel;
 
1128
  defm CMPGTUri : NVJri_base<"cmp.gtu", "CMPGTU", 0b010>, PredRel;
 
1129
}
 
1130
 
 
1131
//===----------------------------------------------------------------------===//
 
1132
// multiclass/template class for the new-value compare jumps instruction
 
1133
// with a register and an hardcoded 0/-1 immediate value.
 
1134
//===----------------------------------------------------------------------===//
 
1135
 
 
1136
let isExtendable = 1, opExtendable = 1, isExtentSigned = 1, opExtentBits = 11 in
 
1137
class NVJ_ConstImm_template<string mnemonic, bits<3> majOp, string ImmVal,
 
1138
                            bit isNegCond, bit isTaken>
 
1139
  : NVInst_V4<(outs),
 
1140
    (ins IntRegs:$src1, brtarget:$offset),
 
1141
    "if ("#!if(isNegCond, "!","")#mnemonic
 
1142
    #"($src1.new, #"#ImmVal#")) jump:"
 
1143
    #!if(isTaken, "t","nt")#" $offset",
 
1144
    []>, Requires<[HasV4T]> {
 
1145
 
 
1146
      let isPredicatedFalse = isNegCond;
 
1147
      let isBrTaken = !if(isTaken, "true", "false");
 
1148
 
 
1149
      bits<3> src1;
 
1150
      bits<11> offset;
 
1151
      let IClass = 0b0010;
 
1152
      let Inst{26} = 0b1;
 
1153
      let Inst{25-23} = majOp;
 
1154
      let Inst{22} = isNegCond;
 
1155
      let Inst{18-16} = src1;
 
1156
      let Inst{13} = isTaken;
 
1157
      let Inst{21-20} = offset{10-9};
 
1158
      let Inst{7-1} = offset{8-2};
 
1159
}
 
1160
 
 
1161
multiclass NVJ_ConstImm_cond<string mnemonic, bits<3> majOp, string ImmVal,
 
1162
                             bit isNegCond> {
 
1163
  // Branch not taken:
 
1164
  def _nt_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 0>;
 
1165
  // Branch taken:
 
1166
  def _t_V4: NVJ_ConstImm_template<mnemonic, majOp, ImmVal, isNegCond, 1>;
 
1167
}
 
1168
 
 
1169
multiclass NVJ_ConstImm_base<string mnemonic, string BaseOp, bits<3> majOp,
 
1170
                             string ImmVal> {
 
1171
  let BaseOpcode = BaseOp#_NVJ_ConstImm in {
 
1172
  defm _t_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 0>; // True cond
 
1173
  defm _f_Jumpnv : NVJ_ConstImm_cond<mnemonic, majOp, ImmVal, 1>; // False Cond
 
1174
  }
 
1175
}
 
1176
 
 
1177
// if ([!]tstbit(Ns.new,#0)) jump:[n]t #r9:2
 
1178
// if ([!]cmp.eq(Ns.new,#-1)) jump:[n]t #r9:2
 
1179
// if ([!]cmp.gt(Ns.new,#-1)) jump:[n]t #r9:2
 
1180
 
 
1181
let isPredicated = 1, isBranch = 1, isNewValue = 1, isTerminator=1,
 
1182
  Defs = [PC], neverHasSideEffects = 1 in {
 
1183
  defm TSTBIT0  : NVJ_ConstImm_base<"tstbit", "TSTBIT", 0b011, "0">, PredRel;
 
1184
  defm CMPEQn1  : NVJ_ConstImm_base<"cmp.eq", "CMPEQ",  0b100, "-1">, PredRel;
 
1185
  defm CMPGTn1  : NVJ_ConstImm_base<"cmp.gt", "CMPGT",  0b101, "-1">, PredRel;
 
1186
}
1284
1187
 
1285
1188
//===----------------------------------------------------------------------===//
1286
1189
// XTYPE/ALU +
2286
2189
 
2287
2190
def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
2288
2191
                       bb:$offset),
2289
 
      (JMP_cNot (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
 
2192
      (JMP_f (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
2290
2193
                bb:$offset)>,
2291
2194
      Requires<[HasV4T]>;
2292
2195
 
2661
2564
//Deallocate frame and return.
2662
2565
//    dealloc_return
2663
2566
let isReturn = 1, isTerminator = 1, isBarrier = 1, isPredicable = 1,
2664
 
  Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1 in {
2665
 
  def DEALLOC_RET_V4 : NVInst_V4<(outs), (ins i32imm:$amt1),
 
2567
  Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1 in {
 
2568
let validSubTargets = HasV4SubT in
 
2569
  def DEALLOC_RET_V4 : LD0Inst<(outs), (ins),
2666
2570
            "dealloc_return",
2667
2571
            []>,
2668
2572
            Requires<[HasV4T]>;
2671
2575
// Restore registers and dealloc return function call.
2672
2576
let isCall = 1, isBarrier = 1, isReturn = 1, isTerminator = 1,
2673
2577
  Defs = [R29, R30, R31, PC] in {
 
2578
let validSubTargets = HasV4SubT in
2674
2579
  def RESTORE_DEALLOC_RET_JMP_V4 : JInst<(outs),
2675
2580
                                   (ins calltarget:$dst),
2676
 
             "jump $dst // Restore_and_dealloc_return",
 
2581
             "jump $dst",
2677
2582
             []>,
2678
2583
             Requires<[HasV4T]>;
2679
2584
}
2681
2586
// Restore registers and dealloc frame before a tail call.
2682
2587
let isCall = 1, isBarrier = 1,
2683
2588
  Defs = [R29, R30, R31, PC] in {
 
2589
let validSubTargets = HasV4SubT in
2684
2590
  def RESTORE_DEALLOC_BEFORE_TAILCALL_V4 : JInst<(outs),
2685
2591
                                           (ins calltarget:$dst),
2686
 
             "call $dst // Restore_and_dealloc_before_tailcall",
 
2592
             "call $dst",
2687
2593
             []>,
2688
2594
             Requires<[HasV4T]>;
2689
2595
}
2700
2606
 
2701
2607
//    if (Ps) dealloc_return
2702
2608
let isReturn = 1, isTerminator = 1,
2703
 
    Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
 
2609
    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
2704
2610
    isPredicated = 1 in {
2705
 
  def DEALLOC_RET_cPt_V4 : NVInst_V4<(outs),
2706
 
                           (ins PredRegs:$src1, i32imm:$amt1),
 
2611
let validSubTargets = HasV4SubT in
 
2612
  def DEALLOC_RET_cPt_V4 : LD0Inst<(outs),
 
2613
                           (ins PredRegs:$src1),
2707
2614
            "if ($src1) dealloc_return",
2708
2615
            []>,
2709
2616
            Requires<[HasV4T]>;
2711
2618
 
2712
2619
//    if (!Ps) dealloc_return
2713
2620
let isReturn = 1, isTerminator = 1,
2714
 
    Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
2715
 
    isPredicated = 1 in {
2716
 
  def DEALLOC_RET_cNotPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
2717
 
                                                     i32imm:$amt1),
 
2621
    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
 
2622
    isPredicated = 1, isPredicatedFalse = 1 in {
 
2623
let validSubTargets = HasV4SubT in
 
2624
  def DEALLOC_RET_cNotPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2718
2625
            "if (!$src1) dealloc_return",
2719
2626
            []>,
2720
2627
            Requires<[HasV4T]>;
2722
2629
 
2723
2630
//    if (Ps.new) dealloc_return:nt
2724
2631
let isReturn = 1, isTerminator = 1,
2725
 
    Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
 
2632
    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
2726
2633
    isPredicated = 1 in {
2727
 
  def DEALLOC_RET_cdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
2728
 
                                                     i32imm:$amt1),
 
2634
let validSubTargets = HasV4SubT in
 
2635
  def DEALLOC_RET_cdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2729
2636
            "if ($src1.new) dealloc_return:nt",
2730
2637
            []>,
2731
2638
            Requires<[HasV4T]>;
2733
2640
 
2734
2641
//    if (!Ps.new) dealloc_return:nt
2735
2642
let isReturn = 1, isTerminator = 1,
2736
 
    Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
2737
 
    isPredicated = 1 in {
2738
 
  def DEALLOC_RET_cNotdnPnt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
2739
 
                                                        i32imm:$amt1),
 
2643
    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
 
2644
    isPredicated = 1, isPredicatedFalse = 1 in {
 
2645
let validSubTargets = HasV4SubT in
 
2646
  def DEALLOC_RET_cNotdnPnt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2740
2647
            "if (!$src1.new) dealloc_return:nt",
2741
2648
            []>,
2742
2649
            Requires<[HasV4T]>;
2744
2651
 
2745
2652
//    if (Ps.new) dealloc_return:t
2746
2653
let isReturn = 1, isTerminator = 1,
2747
 
    Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
 
2654
    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
2748
2655
    isPredicated = 1 in {
2749
 
  def DEALLOC_RET_cdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
2750
 
                                                    i32imm:$amt1),
 
2656
let validSubTargets = HasV4SubT in
 
2657
  def DEALLOC_RET_cdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2751
2658
            "if ($src1.new) dealloc_return:t",
2752
2659
            []>,
2753
2660
            Requires<[HasV4T]>;
2754
2661
}
2755
2662
 
2756
 
//    if (!Ps.new) dealloc_return:nt
 
2663
// if (!Ps.new) dealloc_return:nt
2757
2664
let isReturn = 1, isTerminator = 1,
2758
 
    Defs = [R29, R30, R31, PC], Uses = [R29, R31], neverHasSideEffects = 1,
2759
 
    isPredicated = 1 in {
2760
 
  def DEALLOC_RET_cNotdnPt_V4 : NVInst_V4<(outs), (ins PredRegs:$src1,
2761
 
                                                       i32imm:$amt1),
 
2665
    Defs = [R29, R30, R31, PC], Uses = [R30], neverHasSideEffects = 1,
 
2666
    isPredicated = 1, isPredicatedFalse = 1 in {
 
2667
let validSubTargets = HasV4SubT in
 
2668
  def DEALLOC_RET_cNotdnPt_V4 : LD0Inst<(outs), (ins PredRegs:$src1),
2762
2669
            "if (!$src1.new) dealloc_return:t",
2763
2670
            []>,
2764
2671
            Requires<[HasV4T]>;
2771
2678
                           bit isPredNew> {
2772
2679
  let isPredicatedNew = isPredNew in
2773
2680
  def NAME#_V4 : STInst2<(outs),
2774
 
            (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
 
2681
            (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
2775
2682
            !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
2776
2683
            ") ")#mnemonic#"(##$absaddr) = $src2",
2777
2684
            []>,
2791
2698
  let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
2792
2699
    let opExtendable = 0, isPredicable = 1 in
2793
2700
    def NAME#_V4 : STInst2<(outs),
2794
 
            (ins globaladdressExt:$absaddr, RC:$src),
 
2701
            (ins u0AlwaysExt:$absaddr, RC:$src),
2795
2702
            mnemonic#"(##$absaddr) = $src",
2796
2703
            []>,
2797
2704
            Requires<[HasV4T]>;
2807
2714
                           bit isPredNew> {
2808
2715
  let isPredicatedNew = isPredNew in
2809
2716
  def NAME#_nv_V4 : NVInst_V4<(outs),
2810
 
            (ins PredRegs:$src1, globaladdressExt:$absaddr, RC: $src2),
 
2717
            (ins PredRegs:$src1, u0AlwaysExt:$absaddr, RC: $src2),
2811
2718
            !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
2812
2719
            ") ")#mnemonic#"(##$absaddr) = $src2.new",
2813
2720
            []>,
2827
2734
  let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
2828
2735
    let opExtendable = 0, isPredicable = 1 in
2829
2736
    def NAME#_nv_V4 : NVInst_V4<(outs),
2830
 
            (ins globaladdressExt:$absaddr, RC:$src),
 
2737
            (ins u0AlwaysExt:$absaddr, RC:$src),
2831
2738
            mnemonic#"(##$absaddr) = $src.new",
2832
2739
            []>,
2833
2740
            Requires<[HasV4T]>;
2840
2747
}
2841
2748
 
2842
2749
let addrMode = Absolute in {
 
2750
  let accessSize = ByteAccess in
2843
2751
    defm STrib_abs : ST_Abs<"memb", "STrib", IntRegs>,
2844
2752
                     ST_Abs_nv<"memb", "STrib", IntRegs>, AddrModeRel;
2845
2753
 
 
2754
  let accessSize = HalfWordAccess in
2846
2755
    defm STrih_abs : ST_Abs<"memh", "STrih", IntRegs>,
2847
2756
                     ST_Abs_nv<"memh", "STrih", IntRegs>, AddrModeRel;
2848
2757
 
 
2758
  let accessSize = WordAccess in
2849
2759
    defm STriw_abs : ST_Abs<"memw", "STriw", IntRegs>,
2850
2760
                     ST_Abs_nv<"memw", "STriw", IntRegs>, AddrModeRel;
2851
2761
 
2852
 
  let isNVStorable = 0 in
 
2762
  let accessSize = DoubleWordAccess, isNVStorable = 0 in
2853
2763
    defm STrid_abs : ST_Abs<"memd", "STrid", DoubleRegs>, AddrModeRel;
2854
2764
}
2855
2765
 
2875
2785
// mem[bhwd](#global)=Rt
2876
2786
// if ([!]Pv[.new]) mem[bhwd](##global) = Rt
2877
2787
//===----------------------------------------------------------------------===//
 
2788
let mayStore = 1, isNVStorable = 1 in
2878
2789
multiclass ST_GP<string mnemonic, string BaseOp, RegisterClass RC> {
2879
2790
  let BaseOpcode = BaseOp, isPredicable = 1 in
2880
2791
  def NAME#_V4 : STInst2<(outs),
2909
2820
  }
2910
2821
}
2911
2822
 
2912
 
let validSubTargets = HasV4SubT,  validSubTargets = HasV4SubT in {
2913
 
defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>,
2914
 
              ST_GP_nv<"memd", "STd_GP", DoubleRegs>, NewValueRel ;
2915
 
defm STb_GP : ST_GP<"memb",  "STb_GP", IntRegs>,
2916
 
              ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel ;
2917
 
defm STh_GP : ST_GP<"memh",  "STh_GP", IntRegs>,
2918
 
              ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel ;
2919
 
defm STw_GP : ST_GP<"memw",  "STw_GP", IntRegs>,
2920
 
              ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel ;
 
2823
let validSubTargets = HasV4SubT, neverHasSideEffects = 1 in {
 
2824
  let isNVStorable = 0 in
 
2825
  defm STd_GP : ST_GP <"memd", "STd_GP", DoubleRegs>, PredNewRel;
 
2826
 
 
2827
  defm STb_GP : ST_GP<"memb",  "STb_GP", IntRegs>,
 
2828
                ST_GP_nv<"memb", "STb_GP", IntRegs>, NewValueRel;
 
2829
  defm STh_GP : ST_GP<"memh",  "STh_GP", IntRegs>,
 
2830
                ST_GP_nv<"memh", "STh_GP", IntRegs>, NewValueRel;
 
2831
  defm STw_GP : ST_GP<"memw",  "STw_GP", IntRegs>,
 
2832
                ST_GP_nv<"memw", "STw_GP", IntRegs>, NewValueRel;
2921
2833
}
2922
2834
 
2923
2835
// 64 bit atomic store
2976
2888
                           bit isPredNew> {
2977
2889
  let isPredicatedNew = isPredNew in
2978
2890
  def NAME : LDInst2<(outs RC:$dst),
2979
 
            (ins PredRegs:$src1, globaladdressExt:$absaddr),
 
2891
            (ins PredRegs:$src1, u0AlwaysExt:$absaddr),
2980
2892
            !if(isNot, "if (!$src1", "if ($src1")#!if(isPredNew, ".new) ",
2981
2893
            ") ")#"$dst = "#mnemonic#"(##$absaddr)",
2982
2894
            []>,
2996
2908
  let CextOpcode = CextOp, BaseOpcode = CextOp#_abs in {
2997
2909
    let  opExtendable = 1, isPredicable = 1 in
2998
2910
    def NAME#_V4 : LDInst2<(outs RC:$dst),
2999
 
            (ins globaladdressExt:$absaddr),
 
2911
            (ins u0AlwaysExt:$absaddr),
3000
2912
            "$dst = "#mnemonic#"(##$absaddr)",
3001
2913
            []>,
3002
2914
            Requires<[HasV4T]>;
3009
2921
}
3010
2922
 
3011
2923
let addrMode = Absolute in {
 
2924
  let accessSize = ByteAccess in {
3012
2925
    defm LDrib_abs  : LD_Abs<"memb", "LDrib", IntRegs>, AddrModeRel;
3013
2926
    defm LDriub_abs : LD_Abs<"memub", "LDriub", IntRegs>, AddrModeRel;
 
2927
  }
 
2928
  let accessSize = HalfWordAccess in {
3014
2929
    defm LDrih_abs  : LD_Abs<"memh", "LDrih", IntRegs>, AddrModeRel;
3015
2930
    defm LDriuh_abs : LD_Abs<"memuh", "LDriuh", IntRegs>, AddrModeRel;
 
2931
  }
 
2932
  let accessSize = WordAccess in
3016
2933
    defm LDriw_abs  : LD_Abs<"memw", "LDriw", IntRegs>, AddrModeRel;
 
2934
 
 
2935
  let accessSize = DoubleWordAccess in
3017
2936
    defm LDrid_abs : LD_Abs<"memd",  "LDrid", DoubleRegs>, AddrModeRel;
3018
2937
}
3019
2938
 
3020
 
let Predicates = [HasV4T], AddedComplexity  = 30 in
 
2939
let Predicates = [HasV4T], AddedComplexity  = 30 in {
3021
2940
def : Pat<(i32 (load (HexagonCONST32 tglobaladdr:$absaddr))),
3022
2941
          (LDriw_abs_V4 tglobaladdr: $absaddr)>;
3023
2942
 
3024
 
let Predicates = [HasV4T], AddedComplexity=30 in
3025
2943
def : Pat<(i32 (sextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3026
2944
          (LDrib_abs_V4 tglobaladdr:$absaddr)>;
3027
2945
 
3028
 
let Predicates = [HasV4T], AddedComplexity=30 in
3029
2946
def : Pat<(i32 (zextloadi8 (HexagonCONST32 tglobaladdr:$absaddr))),
3030
2947
          (LDriub_abs_V4 tglobaladdr:$absaddr)>;
3031
2948
 
3032
 
let Predicates = [HasV4T], AddedComplexity=30 in
3033
2949
def : Pat<(i32 (sextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3034
2950
          (LDrih_abs_V4 tglobaladdr:$absaddr)>;
3035
2951
 
3036
 
let Predicates = [HasV4T], AddedComplexity=30 in
3037
2952
def : Pat<(i32 (zextloadi16 (HexagonCONST32 tglobaladdr:$absaddr))),
3038
2953
          (LDriuh_abs_V4 tglobaladdr:$absaddr)>;
 
2954
}
3039
2955
 
3040
2956
//===----------------------------------------------------------------------===//
3041
2957
// multiclass for load instructions with GP-relative addressing mode.
3058
2974
  }
3059
2975
}
3060
2976
 
3061
 
defm LDd_GP  : LD_GP<"memd",  "LDd_GP",  DoubleRegs>;
3062
 
defm LDb_GP  : LD_GP<"memb",  "LDb_GP",  IntRegs>;
3063
 
defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>;
3064
 
defm LDh_GP  : LD_GP<"memh",  "LDh_GP",  IntRegs>;
3065
 
defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>;
3066
 
defm LDw_GP  : LD_GP<"memw",  "LDw_GP",  IntRegs>;
 
2977
defm LDd_GP  : LD_GP<"memd",  "LDd_GP",  DoubleRegs>, PredNewRel;
 
2978
defm LDb_GP  : LD_GP<"memb",  "LDb_GP",  IntRegs>, PredNewRel;
 
2979
defm LDub_GP : LD_GP<"memub", "LDub_GP", IntRegs>, PredNewRel;
 
2980
defm LDh_GP  : LD_GP<"memh",  "LDh_GP",  IntRegs>, PredNewRel;
 
2981
defm LDuh_GP : LD_GP<"memuh", "LDuh_GP", IntRegs>, PredNewRel;
 
2982
defm LDw_GP  : LD_GP<"memw",  "LDw_GP",  IntRegs>, PredNewRel;
3067
2983
 
3068
2984
def : Pat <(atomic_load_64 (HexagonCONST32_GP tglobaladdr:$global)),
3069
2985
           (i64 (LDd_GP_V4 tglobaladdr:$global))>;
3139
3055
 
3140
3056
 
3141
3057
// Transfer global address into a register
3142
 
let AddedComplexity=50, isMoveImm = 1, isReMaterializable = 1 in
3143
 
def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$src1),
3144
 
           "$dst = ##$src1",
 
3058
let isExtended = 1, opExtendable = 1, AddedComplexity=50, isMoveImm = 1,
 
3059
isAsCheapAsAMove = 1, isReMaterializable = 1, validSubTargets = HasV4SubT in
 
3060
def TFRI_V4 : ALU32_ri<(outs IntRegs:$dst), (ins s16Ext:$src1),
 
3061
           "$dst = #$src1",
3145
3062
           [(set IntRegs:$dst, (HexagonCONST32 tglobaladdr:$src1))]>,
3146
3063
           Requires<[HasV4T]>;
3147
3064
 
3150
3067
          (TFRI_V4 tblockaddress:$src1)>,
3151
3068
          Requires<[HasV4T]>;
3152
3069
 
3153
 
let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
 
3070
let isExtended = 1, opExtendable = 2, AddedComplexity=50,
 
3071
neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
3154
3072
def TFRI_cPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3155
 
                           (ins PredRegs:$src1, globaladdress:$src2),
3156
 
           "if($src1) $dst = ##$src2",
 
3073
                           (ins PredRegs:$src1, s16Ext:$src2),
 
3074
           "if($src1) $dst = #$src2",
3157
3075
           []>,
3158
3076
           Requires<[HasV4T]>;
3159
3077
 
3160
 
let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
 
3078
let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
 
3079
neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
3161
3080
def TFRI_cNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3162
 
                              (ins PredRegs:$src1, globaladdress:$src2),
3163
 
           "if(!$src1) $dst = ##$src2",
 
3081
                              (ins PredRegs:$src1, s16Ext:$src2),
 
3082
           "if(!$src1) $dst = #$src2",
3164
3083
           []>,
3165
3084
           Requires<[HasV4T]>;
3166
3085
 
3167
 
let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
 
3086
let isExtended = 1, opExtendable = 2, AddedComplexity=50,
 
3087
neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
3168
3088
def TFRI_cdnPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3169
 
                             (ins PredRegs:$src1, globaladdress:$src2),
3170
 
           "if($src1.new) $dst = ##$src2",
 
3089
                             (ins PredRegs:$src1, s16Ext:$src2),
 
3090
           "if($src1.new) $dst = #$src2",
3171
3091
           []>,
3172
3092
           Requires<[HasV4T]>;
3173
3093
 
3174
 
let AddedComplexity=50, neverHasSideEffects = 1, isPredicated = 1 in
 
3094
let isExtended = 1, opExtendable = 2, AddedComplexity=50, isPredicatedFalse = 1,
 
3095
neverHasSideEffects = 1, isPredicated = 1, validSubTargets = HasV4SubT in
3175
3096
def TFRI_cdnNotPt_V4 : ALU32_ri<(outs IntRegs:$dst),
3176
 
                                (ins PredRegs:$src1, globaladdress:$src2),
3177
 
           "if(!$src1.new) $dst = ##$src2",
 
3097
                                (ins PredRegs:$src1, s16Ext:$src2),
 
3098
           "if(!$src1.new) $dst = #$src2",
3178
3099
           []>,
3179
3100
           Requires<[HasV4T]>;
3180
3101
 
3181
3102
let AddedComplexity = 50, Predicates = [HasV4T] in
3182
3103
def : Pat<(HexagonCONST32_GP tglobaladdr:$src1),
3183
 
           (TFRI_V4 tglobaladdr:$src1)>;
 
3104
           (TFRI_V4 tglobaladdr:$src1)>,
 
3105
           Requires<[HasV4T]>;
3184
3106
 
3185
3107
 
3186
3108
// Load - Indirect with long offset: These instructions take global address
3187
3109
// as an operand
3188
 
let AddedComplexity = 10 in
 
3110
let isExtended = 1, opExtendable = 3, AddedComplexity = 40,
 
3111
validSubTargets = HasV4SubT in
3189
3112
def LDrid_ind_lo_V4 : LDInst<(outs DoubleRegs:$dst),
3190
 
            (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
 
3113
            (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
3191
3114
            "$dst=memd($src1<<#$src2+##$offset)",
3192
3115
            [(set (i64 DoubleRegs:$dst),
3193
3116
                  (load (add (shl IntRegs:$src1, u2ImmPred:$src2),
3194
3117
                        (HexagonCONST32 tglobaladdr:$offset))))]>,
3195
3118
            Requires<[HasV4T]>;
3196
3119
 
3197
 
let AddedComplexity = 10 in
 
3120
let AddedComplexity = 40 in
3198
3121
multiclass LD_indirect_lo<string OpcStr, PatFrag OpNode> {
 
3122
let isExtended = 1, opExtendable = 3, validSubTargets = HasV4SubT in
3199
3123
  def _lo_V4 : LDInst<(outs IntRegs:$dst),
3200
 
            (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$offset),
 
3124
            (ins IntRegs:$src1, u2Imm:$src2, globaladdressExt:$offset),
3201
3125
            !strconcat("$dst = ",
3202
3126
            !strconcat(OpcStr, "($src1<<#$src2+##$offset)")),
3203
3127
            [(set IntRegs:$dst,
3208
3132
 
3209
3133
defm LDrib_ind : LD_indirect_lo<"memb", sextloadi8>;
3210
3134
defm LDriub_ind : LD_indirect_lo<"memub", zextloadi8>;
 
3135
defm LDriub_ind_anyext : LD_indirect_lo<"memub", extloadi8>;
3211
3136
defm LDrih_ind : LD_indirect_lo<"memh", sextloadi16>;
3212
3137
defm LDriuh_ind : LD_indirect_lo<"memuh", zextloadi16>;
 
3138
defm LDriuh_ind_anyext : LD_indirect_lo<"memuh", extloadi16>;
3213
3139
defm LDriw_ind : LD_indirect_lo<"memw", load>;
3214
3140
 
3215
 
// Store - Indirect with long offset: These instructions take global address
3216
 
// as an operand
3217
 
let AddedComplexity = 10 in
3218
 
def STrid_ind_lo_V4 : STInst<(outs),
3219
 
            (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
3220
 
                 DoubleRegs:$src4),
3221
 
            "memd($src1<<#$src2+#$src3) = $src4",
3222
 
            [(store (i64 DoubleRegs:$src4),
3223
 
                 (add (shl IntRegs:$src1, u2ImmPred:$src2),
3224
 
                      (HexagonCONST32 tglobaladdr:$src3)))]>,
3225
 
             Requires<[HasV4T]>;
3226
 
 
3227
 
let AddedComplexity = 10 in
3228
 
multiclass ST_indirect_lo<string OpcStr, PatFrag OpNode> {
3229
 
  def _lo_V4 : STInst<(outs),
3230
 
            (ins IntRegs:$src1, u2Imm:$src2, globaladdress:$src3,
3231
 
                 IntRegs:$src4),
3232
 
            !strconcat(OpcStr, "($src1<<#$src2+##$src3) = $src4"),
3233
 
            [(OpNode (i32 IntRegs:$src4),
3234
 
                 (add (shl IntRegs:$src1, u2ImmPred:$src2),
3235
 
                      (HexagonCONST32 tglobaladdr:$src3)))]>,
3236
 
             Requires<[HasV4T]>;
3237
 
}
3238
 
 
3239
 
defm STrib_ind : ST_indirect_lo<"memb", truncstorei8>;
3240
 
defm STrih_ind : ST_indirect_lo<"memh", truncstorei16>;
3241
 
defm STriw_ind : ST_indirect_lo<"memw", store>;
3242
 
 
3243
 
// Store - absolute addressing mode: These instruction take constant
3244
 
// value as the extended operand.
3245
 
multiclass ST_absimm<string OpcStr> {
3246
 
let isExtended = 1, opExtendable = 0, isPredicable = 1,
3247
 
validSubTargets = HasV4SubT in
3248
 
  def _abs_V4 : STInst2<(outs),
3249
 
            (ins u0AlwaysExt:$src1, IntRegs:$src2),
3250
 
            !strconcat(OpcStr, "(##$src1) = $src2"),
3251
 
            []>,
3252
 
            Requires<[HasV4T]>;
3253
 
 
3254
 
let isExtended = 1, opExtendable = 1, isPredicated = 1,
3255
 
validSubTargets = HasV4SubT in {
3256
 
  def _abs_cPt_V4 : STInst2<(outs),
3257
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3258
 
            !strconcat("if ($src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
3259
 
            []>,
3260
 
            Requires<[HasV4T]>;
3261
 
 
3262
 
  def _abs_cNotPt_V4 : STInst2<(outs),
3263
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3264
 
            !strconcat("if (!$src1)", !strconcat(OpcStr, "(##$src2) = $src3")),
3265
 
            []>,
3266
 
            Requires<[HasV4T]>;
3267
 
 
3268
 
  def _abs_cdnPt_V4 : STInst2<(outs),
3269
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3270
 
            !strconcat("if ($src1.new)",
3271
 
            !strconcat(OpcStr, "(##$src2) = $src3")),
3272
 
            []>,
3273
 
            Requires<[HasV4T]>;
3274
 
 
3275
 
  def _abs_cdnNotPt_V4 : STInst2<(outs),
3276
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3277
 
            !strconcat("if (!$src1.new)",
3278
 
            !strconcat(OpcStr, "(##$src2) = $src3")),
3279
 
            []>,
3280
 
            Requires<[HasV4T]>;
3281
 
}
3282
 
 
3283
 
let isExtended = 1, opExtendable = 0, mayStore = 1, isNVStore = 1,
3284
 
validSubTargets = HasV4SubT in
3285
 
  def _abs_nv_V4 : NVInst_V4<(outs),
3286
 
            (ins u0AlwaysExt:$src1, IntRegs:$src2),
3287
 
            !strconcat(OpcStr, "(##$src1) = $src2.new"),
3288
 
            []>,
3289
 
            Requires<[HasV4T]>;
3290
 
 
3291
 
let isExtended = 1, opExtendable = 1, mayStore = 1, isPredicated = 1,
3292
 
isNVStore = 1, validSubTargets = HasV4SubT in {
3293
 
  def _abs_cPt_nv_V4 : NVInst_V4<(outs),
3294
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3295
 
            !strconcat("if ($src1)",
3296
 
            !strconcat(OpcStr, "(##$src2) = $src3.new")),
3297
 
            []>,
3298
 
            Requires<[HasV4T]>;
3299
 
 
3300
 
  def _abs_cNotPt_nv_V4 : NVInst_V4<(outs),
3301
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3302
 
            !strconcat("if (!$src1)",
3303
 
            !strconcat(OpcStr, "(##$src2) = $src3.new")),
3304
 
            []>,
3305
 
            Requires<[HasV4T]>;
3306
 
 
3307
 
  def _abs_cdnPt_nv_V4 : NVInst_V4<(outs),
3308
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3309
 
            !strconcat("if ($src1.new)",
3310
 
            !strconcat(OpcStr, "(##$src2) = $src3.new")),
3311
 
            []>,
3312
 
            Requires<[HasV4T]>;
3313
 
 
3314
 
  def _abs_cdnNotPt_nv_V4 : NVInst_V4<(outs),
3315
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2, IntRegs:$src3),
3316
 
            !strconcat("if (!$src1.new)",
3317
 
            !strconcat(OpcStr, "(##$src2) = $src3.new")),
3318
 
            []>,
3319
 
            Requires<[HasV4T]>;
3320
 
}
3321
 
}
3322
 
 
3323
 
defm STrib_imm : ST_absimm<"memb">;
3324
 
defm STrih_imm : ST_absimm<"memh">;
3325
 
defm STriw_imm : ST_absimm<"memw">;
 
3141
let AddedComplexity = 40 in
 
3142
def : Pat <(i32 (sextloadi8 (add IntRegs:$src1,
 
3143
                                 (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
 
3144
           (i32 (LDrib_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
 
3145
           Requires<[HasV4T]>;
 
3146
 
 
3147
let AddedComplexity = 40 in
 
3148
def : Pat <(i32 (zextloadi8 (add IntRegs:$src1,
 
3149
                                 (NumUsesBelowThresCONST32 tglobaladdr:$offset)))),
 
3150
           (i32 (LDriub_ind_lo_V4 IntRegs:$src1, 0, tglobaladdr:$offset))>,
 
3151
           Requires<[HasV4T]>;
3326
3152
 
3327
3153
let Predicates = [HasV4T], AddedComplexity  = 30 in {
3328
3154
def : Pat<(truncstorei8 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3329
 
          (STrib_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
 
3155
          (STrib_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3330
3156
 
3331
3157
def : Pat<(truncstorei16 (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3332
 
          (STrih_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
 
3158
          (STrih_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3333
3159
 
3334
3160
def : Pat<(store (i32 IntRegs:$src1), u0AlwaysExtPred:$src2),
3335
 
          (STriw_imm_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
3336
 
}
3337
 
 
3338
 
// Load - absolute addressing mode: These instruction take constant
3339
 
// value as the extended operand
3340
 
 
3341
 
multiclass LD_absimm<string OpcStr> {
3342
 
let isExtended = 1, opExtendable = 1, isPredicable = 1,
3343
 
validSubTargets = HasV4SubT in
3344
 
  def _abs_V4 : LDInst2<(outs IntRegs:$dst),
3345
 
            (ins u0AlwaysExt:$src),
3346
 
            !strconcat("$dst = ",
3347
 
            !strconcat(OpcStr, "(##$src)")),
3348
 
            []>,
3349
 
            Requires<[HasV4T]>;
3350
 
 
3351
 
let isExtended = 1, opExtendable = 2, isPredicated = 1,
3352
 
validSubTargets = HasV4SubT in {
3353
 
  def _abs_cPt_V4 : LDInst2<(outs IntRegs:$dst),
3354
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2),
3355
 
            !strconcat("if ($src1) $dst = ",
3356
 
            !strconcat(OpcStr, "(##$src2)")),
3357
 
            []>,
3358
 
            Requires<[HasV4T]>;
3359
 
 
3360
 
  def _abs_cNotPt_V4 : LDInst2<(outs IntRegs:$dst),
3361
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2),
3362
 
            !strconcat("if (!$src1) $dst = ",
3363
 
            !strconcat(OpcStr, "(##$src2)")),
3364
 
            []>,
3365
 
            Requires<[HasV4T]>;
3366
 
 
3367
 
  def _abs_cdnPt_V4 : LDInst2<(outs IntRegs:$dst),
3368
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2),
3369
 
            !strconcat("if ($src1.new) $dst = ",
3370
 
            !strconcat(OpcStr, "(##$src2)")),
3371
 
            []>,
3372
 
            Requires<[HasV4T]>;
3373
 
 
3374
 
  def _abs_cdnNotPt_V4 : LDInst2<(outs IntRegs:$dst),
3375
 
            (ins PredRegs:$src1, u0AlwaysExt:$src2),
3376
 
            !strconcat("if (!$src1.new) $dst = ",
3377
 
            !strconcat(OpcStr, "(##$src2)")),
3378
 
            []>,
3379
 
            Requires<[HasV4T]>;
3380
 
}
3381
 
}
3382
 
 
3383
 
defm LDrib_imm  : LD_absimm<"memb">;
3384
 
defm LDriub_imm : LD_absimm<"memub">;
3385
 
defm LDrih_imm  : LD_absimm<"memh">;
3386
 
defm LDriuh_imm : LD_absimm<"memuh">;
3387
 
defm LDriw_imm  : LD_absimm<"memw">;
 
3161
          (STriw_abs_V4 u0AlwaysExtPred:$src2, IntRegs: $src1)>;
 
3162
}
3388
3163
 
3389
3164
let Predicates = [HasV4T], AddedComplexity  = 30 in {
3390
3165
def : Pat<(i32 (load u0AlwaysExtPred:$src)),
3391
 
          (LDriw_imm_abs_V4 u0AlwaysExtPred:$src)>;
 
3166
          (LDriw_abs_V4 u0AlwaysExtPred:$src)>;
3392
3167
 
3393
3168
def : Pat<(i32 (sextloadi8 u0AlwaysExtPred:$src)),
3394
 
          (LDrib_imm_abs_V4 u0AlwaysExtPred:$src)>;
 
3169
          (LDrib_abs_V4 u0AlwaysExtPred:$src)>;
3395
3170
 
3396
3171
def : Pat<(i32 (zextloadi8 u0AlwaysExtPred:$src)),
3397
 
          (LDriub_imm_abs_V4 u0AlwaysExtPred:$src)>;
 
3172
          (LDriub_abs_V4 u0AlwaysExtPred:$src)>;
3398
3173
 
3399
3174
def : Pat<(i32 (sextloadi16 u0AlwaysExtPred:$src)),
3400
 
          (LDrih_imm_abs_V4 u0AlwaysExtPred:$src)>;
 
3175
          (LDrih_abs_V4 u0AlwaysExtPred:$src)>;
3401
3176
 
3402
3177
def : Pat<(i32 (zextloadi16 u0AlwaysExtPred:$src)),
3403
 
          (LDriuh_imm_abs_V4 u0AlwaysExtPred:$src)>;
 
3178
          (LDriuh_abs_V4 u0AlwaysExtPred:$src)>;
3404
3179
}
3405
3180
 
3406
 
// Indexed store double word - global address.
 
3181
// Indexed store word - global address.
3407
3182
// memw(Rs+#u6:2)=#S8
3408
3183
let AddedComplexity = 10 in
3409
3184
def STriw_offset_ext_V4 : STInst<(outs),
3413
3188
                    (add IntRegs:$src1, u6_2ImmPred:$src2))]>,
3414
3189
            Requires<[HasV4T]>;
3415
3190
 
 
3191
def : Pat<(i64 (ctlz (i64 DoubleRegs:$src1))),
 
3192
          (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTLZ64_rr DoubleRegs:$src1))))>,
 
3193
          Requires<[HasV4T]>;
 
3194
 
 
3195
def : Pat<(i64 (cttz (i64 DoubleRegs:$src1))),
 
3196
          (i64 (COMBINE_Ir_V4 (i32 0), (i32 (CTTZ64_rr DoubleRegs:$src1))))>,
 
3197
          Requires<[HasV4T]>;
 
3198
 
 
3199
 
 
3200
// i8 -> i64 loads
 
3201
// We need a complexity of 120 here to overide preceeding handling of
 
3202
// zextloadi8.
 
3203
let Predicates = [HasV4T], AddedComplexity = 120 in {
 
3204
def:  Pat <(i64 (extloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
 
3205
      (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 tglobaladdr:$addr)))>;
 
3206
 
 
3207
def:  Pat <(i64 (zextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
 
3208
      (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 tglobaladdr:$addr)))>;
 
3209
 
 
3210
def:  Pat <(i64 (sextloadi8 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
 
3211
      (i64 (SXTW (LDrib_abs_V4 tglobaladdr:$addr)))>;
 
3212
 
 
3213
def:  Pat <(i64 (extloadi8 FoldGlobalAddr:$addr)),
 
3214
      (i64 (COMBINE_Ir_V4 0, (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
 
3215
 
 
3216
def:  Pat <(i64 (zextloadi8 FoldGlobalAddr:$addr)),
 
3217
      (i64 (COMBINE_Ir_V4 0, (LDriub_abs_V4 FoldGlobalAddr:$addr)))>;
 
3218
 
 
3219
def:  Pat <(i64 (sextloadi8 FoldGlobalAddr:$addr)),
 
3220
      (i64 (SXTW (LDrib_abs_V4 FoldGlobalAddr:$addr)))>;
 
3221
}
 
3222
// i16 -> i64 loads
 
3223
// We need a complexity of 120 here to overide preceeding handling of
 
3224
// zextloadi16.
 
3225
let AddedComplexity = 120 in {
 
3226
def:  Pat <(i64 (extloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
 
3227
      (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 tglobaladdr:$addr)))>,
 
3228
      Requires<[HasV4T]>;
 
3229
 
 
3230
def:  Pat <(i64 (zextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
 
3231
      (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 tglobaladdr:$addr)))>,
 
3232
      Requires<[HasV4T]>;
 
3233
 
 
3234
def:  Pat <(i64 (sextloadi16 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
 
3235
      (i64 (SXTW (LDrih_abs_V4 tglobaladdr:$addr)))>,
 
3236
      Requires<[HasV4T]>;
 
3237
 
 
3238
def:  Pat <(i64 (extloadi16 FoldGlobalAddr:$addr)),
 
3239
      (i64 (COMBINE_Ir_V4 0, (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
 
3240
      Requires<[HasV4T]>;
 
3241
 
 
3242
def:  Pat <(i64 (zextloadi16 FoldGlobalAddr:$addr)),
 
3243
      (i64 (COMBINE_Ir_V4 0, (LDriuh_abs_V4 FoldGlobalAddr:$addr)))>,
 
3244
      Requires<[HasV4T]>;
 
3245
 
 
3246
def:  Pat <(i64 (sextloadi16 FoldGlobalAddr:$addr)),
 
3247
      (i64 (SXTW (LDrih_abs_V4 FoldGlobalAddr:$addr)))>,
 
3248
      Requires<[HasV4T]>;
 
3249
}
 
3250
// i32->i64 loads
 
3251
// We need a complexity of 120 here to overide preceeding handling of
 
3252
// zextloadi32.
 
3253
let AddedComplexity = 120 in {
 
3254
def:  Pat <(i64 (extloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
 
3255
      (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
 
3256
      Requires<[HasV4T]>;
 
3257
 
 
3258
def:  Pat <(i64 (zextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
 
3259
      (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 tglobaladdr:$addr)))>,
 
3260
      Requires<[HasV4T]>;
 
3261
 
 
3262
def:  Pat <(i64 (sextloadi32 (NumUsesBelowThresCONST32 tglobaladdr:$addr))),
 
3263
      (i64 (SXTW (LDriw_abs_V4 tglobaladdr:$addr)))>,
 
3264
      Requires<[HasV4T]>;
 
3265
 
 
3266
def:  Pat <(i64 (extloadi32 FoldGlobalAddr:$addr)),
 
3267
      (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
 
3268
      Requires<[HasV4T]>;
 
3269
 
 
3270
def:  Pat <(i64 (zextloadi32 FoldGlobalAddr:$addr)),
 
3271
      (i64 (COMBINE_Ir_V4 0, (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
 
3272
      Requires<[HasV4T]>;
 
3273
 
 
3274
def:  Pat <(i64 (sextloadi32 FoldGlobalAddr:$addr)),
 
3275
      (i64 (SXTW (LDriw_abs_V4 FoldGlobalAddr:$addr)))>,
 
3276
      Requires<[HasV4T]>;
 
3277
}
3416
3278
 
3417
3279
// Indexed store double word - global address.
3418
3280
// memw(Rs+#u6:2)=#S8