Add parameter to pattern classes to enable an itinerary to be specified for instructions. For now just use the existing itineraries or NoItinerary.
llvm-svn: 78321
This commit is contained in:
		
							parent
							
								
									0c4a959b28
								
							
						
					
					
						commit
						b062c236c5
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -340,18 +340,18 @@ include "ARMInstrFormats.td"
 | 
			
		|||
multiclass AsI1_bin_irs<bits<4> opcod, string opc, PatFrag opnode,
 | 
			
		||||
                        bit Commutable = 0> {
 | 
			
		||||
  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
 | 
			
		||||
               opc, " $dst, $a, $b",
 | 
			
		||||
               IIC_iALU, opc, " $dst, $a, $b",
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
 | 
			
		||||
    let Inst{25} = 1;
 | 
			
		||||
  }
 | 
			
		||||
  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
 | 
			
		||||
               opc, " $dst, $a, $b",
 | 
			
		||||
               IIC_iALU, opc, " $dst, $a, $b",
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
 | 
			
		||||
    let Inst{25} = 0;
 | 
			
		||||
    let isCommutable = Commutable;
 | 
			
		||||
  }
 | 
			
		||||
  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
 | 
			
		||||
               opc, " $dst, $a, $b",
 | 
			
		||||
               IIC_iALU, opc, " $dst, $a, $b",
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
 | 
			
		||||
    let Inst{25} = 0;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -363,18 +363,18 @@ let Defs = [CPSR] in {
 | 
			
		|||
multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
 | 
			
		||||
                         bit Commutable = 0> {
 | 
			
		||||
  def ri : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
 | 
			
		||||
               opc, "s $dst, $a, $b",
 | 
			
		||||
               IIC_iALU, opc, "s $dst, $a, $b",
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]> {
 | 
			
		||||
    let Inst{25} = 1;
 | 
			
		||||
  }
 | 
			
		||||
  def rr : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm,
 | 
			
		||||
               opc, "s $dst, $a, $b",
 | 
			
		||||
               IIC_iALU, opc, "s $dst, $a, $b",
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]> {
 | 
			
		||||
    let isCommutable = Commutable;
 | 
			
		||||
	let Inst{25} = 0;
 | 
			
		||||
  }
 | 
			
		||||
  def rs : AI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
 | 
			
		||||
               opc, "s $dst, $a, $b",
 | 
			
		||||
               IIC_iALU, opc, "s $dst, $a, $b",
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
 | 
			
		||||
    let Inst{25} = 0;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -387,18 +387,18 @@ multiclass AI1_bin_s_irs<bits<4> opcod, string opc, PatFrag opnode,
 | 
			
		|||
let Defs = [CPSR] in {
 | 
			
		||||
multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
 | 
			
		||||
                       bit Commutable = 0> {
 | 
			
		||||
  def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm,
 | 
			
		||||
  def ri : AI1<opcod, (outs), (ins GPR:$a, so_imm:$b), DPFrm, IIC_iALU,
 | 
			
		||||
               opc, " $a, $b",
 | 
			
		||||
               [(opnode GPR:$a, so_imm:$b)]> {
 | 
			
		||||
    let Inst{25} = 1;
 | 
			
		||||
  }
 | 
			
		||||
  def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm,
 | 
			
		||||
  def rr : AI1<opcod, (outs), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALU,
 | 
			
		||||
               opc, " $a, $b",
 | 
			
		||||
               [(opnode GPR:$a, GPR:$b)]> {
 | 
			
		||||
    let Inst{25} = 0;
 | 
			
		||||
    let isCommutable = Commutable;
 | 
			
		||||
  }
 | 
			
		||||
  def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
 | 
			
		||||
  def rs : AI1<opcod, (outs), (ins GPR:$a, so_reg:$b), DPSoRegFrm, IIC_iALU,
 | 
			
		||||
               opc, " $a, $b",
 | 
			
		||||
               [(opnode GPR:$a, so_reg:$b)]> {
 | 
			
		||||
    let Inst{25} = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -411,13 +411,13 @@ multiclass AI1_cmp_irs<bits<4> opcod, string opc, PatFrag opnode,
 | 
			
		|||
/// FIXME: Remove the 'r' variant. Its rot_imm is zero.
 | 
			
		||||
multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
 | 
			
		||||
  def r     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$Src),
 | 
			
		||||
                 opc, " $dst, $Src",
 | 
			
		||||
                 IIC_iALU, opc, " $dst, $Src",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$Src))]>,
 | 
			
		||||
              Requires<[IsARM, HasV6]> {
 | 
			
		||||
                let Inst{19-16} = 0b1111;
 | 
			
		||||
              }
 | 
			
		||||
  def r_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$Src, i32imm:$rot),
 | 
			
		||||
                 opc, " $dst, $Src, ror $rot",
 | 
			
		||||
                 IIC_iALU, opc, " $dst, $Src, ror $rot",
 | 
			
		||||
                 [(set GPR:$dst, (opnode (rotr GPR:$Src, rot_imm:$rot)))]>,
 | 
			
		||||
              Requires<[IsARM, HasV6]> {
 | 
			
		||||
                let Inst{19-16} = 0b1111;
 | 
			
		||||
| 
						 | 
				
			
			@ -428,11 +428,11 @@ multiclass AI_unary_rrot<bits<8> opcod, string opc, PatFrag opnode> {
 | 
			
		|||
/// register and one whose operand is a register rotated by 8/16/24.
 | 
			
		||||
multiclass AI_bin_rrot<bits<8> opcod, string opc, PatFrag opnode> {
 | 
			
		||||
  def rr     : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
 | 
			
		||||
                  opc, " $dst, $LHS, $RHS",
 | 
			
		||||
                  IIC_iALU, opc, " $dst, $LHS, $RHS",
 | 
			
		||||
                  [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>,
 | 
			
		||||
                  Requires<[IsARM, HasV6]>;
 | 
			
		||||
  def rr_rot : AExtI<opcod, (outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
 | 
			
		||||
                  opc, " $dst, $LHS, $RHS, ror $rot",
 | 
			
		||||
                  IIC_iALU, opc, " $dst, $LHS, $RHS, ror $rot",
 | 
			
		||||
                  [(set GPR:$dst, (opnode GPR:$LHS,
 | 
			
		||||
                                          (rotr GPR:$RHS, rot_imm:$rot)))]>,
 | 
			
		||||
                  Requires<[IsARM, HasV6]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -443,41 +443,41 @@ let Uses = [CPSR] in {
 | 
			
		|||
multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
 | 
			
		||||
                             bit Commutable = 0> {
 | 
			
		||||
  def ri : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
 | 
			
		||||
                DPFrm, opc, " $dst, $a, $b",
 | 
			
		||||
                DPFrm, IIC_iALU, opc, " $dst, $a, $b",
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
 | 
			
		||||
               Requires<[IsARM, CarryDefIsUnused]> {
 | 
			
		||||
    let Inst{25} = 1;
 | 
			
		||||
  }
 | 
			
		||||
  def rr : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
                DPFrm, opc, " $dst, $a, $b",
 | 
			
		||||
                DPFrm, IIC_iALU, opc, " $dst, $a, $b",
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
 | 
			
		||||
               Requires<[IsARM, CarryDefIsUnused]> {
 | 
			
		||||
    let isCommutable = Commutable;
 | 
			
		||||
    let Inst{25} = 0;
 | 
			
		||||
  }
 | 
			
		||||
  def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
 | 
			
		||||
                DPSoRegFrm, opc, " $dst, $a, $b",
 | 
			
		||||
                DPSoRegFrm, IIC_iALU, opc, " $dst, $a, $b",
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
 | 
			
		||||
               Requires<[IsARM, CarryDefIsUnused]> {
 | 
			
		||||
    let Inst{25} = 0;
 | 
			
		||||
  }
 | 
			
		||||
  // Carry setting variants
 | 
			
		||||
  def Sri : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
 | 
			
		||||
                DPFrm, !strconcat(opc, "s $dst, $a, $b"),
 | 
			
		||||
                DPFrm, IIC_iALU, !strconcat(opc, "s $dst, $a, $b"),
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, so_imm:$b))]>,
 | 
			
		||||
               Requires<[IsARM, CarryDefIsUsed]> {
 | 
			
		||||
    let Defs = [CPSR];
 | 
			
		||||
    let Inst{25} = 1;
 | 
			
		||||
  }
 | 
			
		||||
  def Srr : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
                DPFrm, !strconcat(opc, "s $dst, $a, $b"),
 | 
			
		||||
                DPFrm, IIC_iALU, !strconcat(opc, "s $dst, $a, $b"),
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, GPR:$b))]>,
 | 
			
		||||
               Requires<[IsARM, CarryDefIsUsed]> {
 | 
			
		||||
    let Defs = [CPSR];
 | 
			
		||||
    let Inst{25} = 0;
 | 
			
		||||
  }
 | 
			
		||||
  def Srs : AXI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
 | 
			
		||||
                DPSoRegFrm, !strconcat(opc, "s $dst, $a, $b"),
 | 
			
		||||
                DPSoRegFrm, IIC_iALU, !strconcat(opc, "s $dst, $a, $b"),
 | 
			
		||||
               [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]>,
 | 
			
		||||
               Requires<[IsARM, CarryDefIsUsed]> {
 | 
			
		||||
    let Defs = [CPSR];
 | 
			
		||||
| 
						 | 
				
			
			@ -501,23 +501,23 @@ multiclass AI1_adde_sube_irs<bits<4> opcod, string opc, PatFrag opnode,
 | 
			
		|||
let neverHasSideEffects = 1, isNotDuplicable = 1 in
 | 
			
		||||
def CONSTPOOL_ENTRY :
 | 
			
		||||
PseudoInst<(outs), (ins cpinst_operand:$instid, cpinst_operand:$cpidx,
 | 
			
		||||
                    i32imm:$size),
 | 
			
		||||
                    i32imm:$size), NoItinerary,
 | 
			
		||||
           "${instid:label} ${cpidx:cpentry}", []>;
 | 
			
		||||
 | 
			
		||||
let Defs = [SP], Uses = [SP] in {
 | 
			
		||||
def ADJCALLSTACKUP :
 | 
			
		||||
PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p),
 | 
			
		||||
PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2, pred:$p), NoItinerary,
 | 
			
		||||
           "@ ADJCALLSTACKUP $amt1",
 | 
			
		||||
           [(ARMcallseq_end timm:$amt1, timm:$amt2)]>;
 | 
			
		||||
 | 
			
		||||
def ADJCALLSTACKDOWN : 
 | 
			
		||||
PseudoInst<(outs), (ins i32imm:$amt, pred:$p),
 | 
			
		||||
PseudoInst<(outs), (ins i32imm:$amt, pred:$p), NoItinerary,
 | 
			
		||||
           "@ ADJCALLSTACKDOWN $amt",
 | 
			
		||||
           [(ARMcallseq_start timm:$amt)]>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def DWARF_LOC :
 | 
			
		||||
PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
 | 
			
		||||
PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file), NoItinerary,
 | 
			
		||||
           ".loc $file, $line, $col",
 | 
			
		||||
           [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -525,42 +525,42 @@ PseudoInst<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file),
 | 
			
		|||
// Address computation and loads and stores in PIC mode.
 | 
			
		||||
let isNotDuplicable = 1 in {
 | 
			
		||||
def PICADD : AXI1<0b0100, (outs GPR:$dst), (ins GPR:$a, pclabel:$cp, pred:$p),
 | 
			
		||||
                  Pseudo, "$cp:\n\tadd$p $dst, pc, $a",
 | 
			
		||||
                  Pseudo, IIC_iALU, "$cp:\n\tadd$p $dst, pc, $a",
 | 
			
		||||
                   [(set GPR:$dst, (ARMpic_add GPR:$a, imm:$cp))]>;
 | 
			
		||||
 | 
			
		||||
let AddedComplexity = 10 in {
 | 
			
		||||
let canFoldAsLoad = 1 in
 | 
			
		||||
def PICLDR  : AXI2ldw<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
 | 
			
		||||
                  Pseudo, "${addr:label}:\n\tldr$p $dst, $addr",
 | 
			
		||||
                  Pseudo, IIC_iLoad, "${addr:label}:\n\tldr$p $dst, $addr",
 | 
			
		||||
                  [(set GPR:$dst, (load addrmodepc:$addr))]>;
 | 
			
		||||
 | 
			
		||||
def PICLDRH : AXI3ldh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
 | 
			
		||||
                  Pseudo, "${addr:label}:\n\tldr${p}h $dst, $addr",
 | 
			
		||||
                  Pseudo, IIC_iLoad, "${addr:label}:\n\tldr${p}h $dst, $addr",
 | 
			
		||||
                  [(set GPR:$dst, (zextloadi16 addrmodepc:$addr))]>;
 | 
			
		||||
 | 
			
		||||
def PICLDRB : AXI2ldb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
 | 
			
		||||
                  Pseudo, "${addr:label}:\n\tldr${p}b $dst, $addr",
 | 
			
		||||
                  Pseudo, IIC_iLoad, "${addr:label}:\n\tldr${p}b $dst, $addr",
 | 
			
		||||
                  [(set GPR:$dst, (zextloadi8 addrmodepc:$addr))]>;
 | 
			
		||||
 | 
			
		||||
def PICLDRSH : AXI3ldsh<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
 | 
			
		||||
                  Pseudo, "${addr:label}:\n\tldr${p}sh $dst, $addr",
 | 
			
		||||
                  Pseudo, IIC_iLoad, "${addr:label}:\n\tldr${p}sh $dst, $addr",
 | 
			
		||||
                  [(set GPR:$dst, (sextloadi16 addrmodepc:$addr))]>;
 | 
			
		||||
 | 
			
		||||
def PICLDRSB : AXI3ldsb<(outs GPR:$dst), (ins addrmodepc:$addr, pred:$p),
 | 
			
		||||
                  Pseudo, "${addr:label}:\n\tldr${p}sb $dst, $addr",
 | 
			
		||||
                  Pseudo, IIC_iLoad, "${addr:label}:\n\tldr${p}sb $dst, $addr",
 | 
			
		||||
                  [(set GPR:$dst, (sextloadi8 addrmodepc:$addr))]>;
 | 
			
		||||
}
 | 
			
		||||
let AddedComplexity = 10 in {
 | 
			
		||||
def PICSTR  : AXI2stw<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
 | 
			
		||||
               Pseudo, "${addr:label}:\n\tstr$p $src, $addr",
 | 
			
		||||
               Pseudo, IIC_iStore, "${addr:label}:\n\tstr$p $src, $addr",
 | 
			
		||||
               [(store GPR:$src, addrmodepc:$addr)]>;
 | 
			
		||||
 | 
			
		||||
def PICSTRH : AXI3sth<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
 | 
			
		||||
               Pseudo, "${addr:label}:\n\tstr${p}h $src, $addr",
 | 
			
		||||
               Pseudo, IIC_iStore, "${addr:label}:\n\tstr${p}h $src, $addr",
 | 
			
		||||
               [(truncstorei16 GPR:$src, addrmodepc:$addr)]>;
 | 
			
		||||
 | 
			
		||||
def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
 | 
			
		||||
               Pseudo, "${addr:label}:\n\tstr${p}b $src, $addr",
 | 
			
		||||
               Pseudo, IIC_iStore, "${addr:label}:\n\tstr${p}b $src, $addr",
 | 
			
		||||
               [(truncstorei8 GPR:$src, addrmodepc:$addr)]>;
 | 
			
		||||
}
 | 
			
		||||
} // isNotDuplicable = 1
 | 
			
		||||
| 
						 | 
				
			
			@ -568,7 +568,8 @@ def PICSTRB : AXI2stb<(outs), (ins GPR:$src, addrmodepc:$addr, pred:$p),
 | 
			
		|||
 | 
			
		||||
// LEApcrel - Load a pc-relative address into a register without offending the
 | 
			
		||||
// assembler.
 | 
			
		||||
def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p), Pseudo,
 | 
			
		||||
def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p),
 | 
			
		||||
                    Pseudo, IIC_iLoad,
 | 
			
		||||
            !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, ($label-(",
 | 
			
		||||
                                  "${:private}PCRELL${:uid}+8))\n"),
 | 
			
		||||
                       !strconcat("${:private}PCRELL${:uid}:\n\t",
 | 
			
		||||
| 
						 | 
				
			
			@ -577,7 +578,7 @@ def LEApcrel : AXI1<0x0, (outs GPR:$dst), (ins i32imm:$label, pred:$p), Pseudo,
 | 
			
		|||
 | 
			
		||||
def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
 | 
			
		||||
                           (ins i32imm:$label, i32imm:$id, pred:$p),
 | 
			
		||||
          Pseudo,
 | 
			
		||||
          Pseudo, IIC_iLoad,
 | 
			
		||||
   !strconcat(!strconcat(".set ${:private}PCRELV${:uid}, "
 | 
			
		||||
                         "(${label}_${id:no_hash}-(",
 | 
			
		||||
                                  "${:private}PCRELL${:uid}+8))\n"),
 | 
			
		||||
| 
						 | 
				
			
			@ -592,7 +593,8 @@ def LEApcrelJT : AXI1<0x0, (outs GPR:$dst),
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
let isReturn = 1, isTerminator = 1 in
 | 
			
		||||
  def BX_RET : AI<(outs), (ins), BrMiscFrm, "bx", " lr", [(ARMretflag)]> {
 | 
			
		||||
  def BX_RET : AI<(outs), (ins), BrMiscFrm, IIC_Br, 
 | 
			
		||||
                  "bx", " lr", [(ARMretflag)]> {
 | 
			
		||||
  let Inst{7-4}   = 0b0001;
 | 
			
		||||
  let Inst{19-8}  = 0b111111111111;
 | 
			
		||||
  let Inst{27-20} = 0b00010010;
 | 
			
		||||
| 
						 | 
				
			
			@ -605,7 +607,7 @@ let isReturn = 1, isTerminator = 1 in
 | 
			
		|||
let isReturn = 1, isTerminator = 1, mayLoad = 1 in
 | 
			
		||||
  def LDM_RET : AXI4ld<(outs),
 | 
			
		||||
                    (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
 | 
			
		||||
                    LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
 | 
			
		||||
                    LdStMulFrm, IIC_Br, "ldm${p}${addr:submode} $addr, $dst1",
 | 
			
		||||
                    []>;
 | 
			
		||||
 | 
			
		||||
// On non-Darwin platforms R9 is callee-saved.
 | 
			
		||||
| 
						 | 
				
			
			@ -615,18 +617,18 @@ let isCall = 1, Itinerary = IIC_Br,
 | 
			
		|||
          D16, D17, D18, D19, D20, D21, D22, D23,
 | 
			
		||||
          D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in {
 | 
			
		||||
  def BL  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
 | 
			
		||||
                "bl ${func:call}",
 | 
			
		||||
                IIC_Br, "bl ${func:call}",
 | 
			
		||||
                [(ARMcall tglobaladdr:$func)]>,
 | 
			
		||||
            Requires<[IsARM, IsNotDarwin]>;
 | 
			
		||||
 | 
			
		||||
  def BL_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
 | 
			
		||||
                   "bl", " ${func:call}",
 | 
			
		||||
                   IIC_Br, "bl", " ${func:call}",
 | 
			
		||||
                   [(ARMcall_pred tglobaladdr:$func)]>,
 | 
			
		||||
                Requires<[IsARM, IsNotDarwin]>;
 | 
			
		||||
 | 
			
		||||
  // ARMv5T and above
 | 
			
		||||
  def BLX : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
 | 
			
		||||
                "blx $func",
 | 
			
		||||
                IIC_Br, "blx $func",
 | 
			
		||||
                [(ARMcall GPR:$func)]>,
 | 
			
		||||
            Requires<[IsARM, HasV5T, IsNotDarwin]> {
 | 
			
		||||
    let Inst{7-4}   = 0b0011;
 | 
			
		||||
| 
						 | 
				
			
			@ -636,7 +638,7 @@ let isCall = 1, Itinerary = IIC_Br,
 | 
			
		|||
 | 
			
		||||
  // ARMv4T
 | 
			
		||||
  def BX : ABXIx2<(outs), (ins GPR:$func, variable_ops),
 | 
			
		||||
                   "mov lr, pc\n\tbx $func",
 | 
			
		||||
                  IIC_Br, "mov lr, pc\n\tbx $func",
 | 
			
		||||
                  [(ARMcall_nolink GPR:$func)]>,
 | 
			
		||||
           Requires<[IsARM, IsNotDarwin]> {
 | 
			
		||||
    let Inst{7-4}   = 0b0001;
 | 
			
		||||
| 
						 | 
				
			
			@ -652,17 +654,17 @@ let isCall = 1, Itinerary = IIC_Br,
 | 
			
		|||
          D16, D17, D18, D19, D20, D21, D22, D23,
 | 
			
		||||
          D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in {
 | 
			
		||||
  def BLr9  : ABXI<0b1011, (outs), (ins i32imm:$func, variable_ops),
 | 
			
		||||
                "bl ${func:call}",
 | 
			
		||||
                IIC_Br, "bl ${func:call}",
 | 
			
		||||
                [(ARMcall tglobaladdr:$func)]>, Requires<[IsARM, IsDarwin]>;
 | 
			
		||||
 | 
			
		||||
  def BLr9_pred : ABI<0b1011, (outs), (ins i32imm:$func, variable_ops),
 | 
			
		||||
                   "bl", " ${func:call}",
 | 
			
		||||
                   IIC_Br, "bl", " ${func:call}",
 | 
			
		||||
                   [(ARMcall_pred tglobaladdr:$func)]>,
 | 
			
		||||
                  Requires<[IsARM, IsDarwin]>;
 | 
			
		||||
 | 
			
		||||
  // ARMv5T and above
 | 
			
		||||
  def BLXr9 : AXI<(outs), (ins GPR:$func, variable_ops), BrMiscFrm,
 | 
			
		||||
                "blx $func",
 | 
			
		||||
                IIC_Br, "blx $func",
 | 
			
		||||
                [(ARMcall GPR:$func)]>, Requires<[IsARM, HasV5T, IsDarwin]> {
 | 
			
		||||
    let Inst{7-4}   = 0b0011;
 | 
			
		||||
    let Inst{19-8}  = 0b111111111111;
 | 
			
		||||
| 
						 | 
				
			
			@ -671,7 +673,7 @@ let isCall = 1, Itinerary = IIC_Br,
 | 
			
		|||
 | 
			
		||||
  // ARMv4T
 | 
			
		||||
  def BXr9 : ABXIx2<(outs), (ins GPR:$func, variable_ops),
 | 
			
		||||
                   "mov lr, pc\n\tbx $func",
 | 
			
		||||
                  IIC_Br, "mov lr, pc\n\tbx $func",
 | 
			
		||||
                  [(ARMcall_nolink GPR:$func)]>, Requires<[IsARM, IsDarwin]> {
 | 
			
		||||
    let Inst{7-4}   = 0b0001;
 | 
			
		||||
    let Inst{19-8}  = 0b111111111111;
 | 
			
		||||
| 
						 | 
				
			
			@ -683,12 +685,12 @@ let isBranch = 1, isTerminator = 1, Itinerary = IIC_Br in {
 | 
			
		|||
  // B is "predicable" since it can be xformed into a Bcc.
 | 
			
		||||
  let isBarrier = 1 in {
 | 
			
		||||
    let isPredicable = 1 in
 | 
			
		||||
    def B : ABXI<0b1010, (outs), (ins brtarget:$target), "b $target",
 | 
			
		||||
                [(br bb:$target)]>;
 | 
			
		||||
    def B : ABXI<0b1010, (outs), (ins brtarget:$target), IIC_Br,
 | 
			
		||||
                "b $target", [(br bb:$target)]>;
 | 
			
		||||
 | 
			
		||||
  let isNotDuplicable = 1, isIndirectBranch = 1 in {
 | 
			
		||||
  def BR_JTr : JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
 | 
			
		||||
                    "mov pc, $target \n$jt",
 | 
			
		||||
                    IIC_Br, "mov pc, $target \n$jt",
 | 
			
		||||
                    [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]> {
 | 
			
		||||
    let Inst{20}    = 0; // S Bit
 | 
			
		||||
    let Inst{24-21} = 0b1101;
 | 
			
		||||
| 
						 | 
				
			
			@ -696,7 +698,7 @@ let isBranch = 1, isTerminator = 1, Itinerary = IIC_Br in {
 | 
			
		|||
  }
 | 
			
		||||
  def BR_JTm : JTI<(outs),
 | 
			
		||||
                   (ins addrmode2:$target, jtblock_operand:$jt, i32imm:$id),
 | 
			
		||||
                   "ldr pc, $target \n$jt",
 | 
			
		||||
                   IIC_Br, "ldr pc, $target \n$jt",
 | 
			
		||||
                   [(ARMbrjt (i32 (load addrmode2:$target)), tjumptable:$jt,
 | 
			
		||||
                     imm:$id)]> {
 | 
			
		||||
    let Inst{20}    = 1; // L bit
 | 
			
		||||
| 
						 | 
				
			
			@ -707,7 +709,7 @@ let isBranch = 1, isTerminator = 1, Itinerary = IIC_Br in {
 | 
			
		|||
  }
 | 
			
		||||
  def BR_JTadd : JTI<(outs),
 | 
			
		||||
                   (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
 | 
			
		||||
                     "add pc, $target, $idx \n$jt",
 | 
			
		||||
                    IIC_Br, "add pc, $target, $idx \n$jt",
 | 
			
		||||
                    [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt,
 | 
			
		||||
                      imm:$id)]> {
 | 
			
		||||
    let Inst{20}    = 0; // S bit
 | 
			
		||||
| 
						 | 
				
			
			@ -720,7 +722,7 @@ let isBranch = 1, isTerminator = 1, Itinerary = IIC_Br in {
 | 
			
		|||
  // FIXME: should be able to write a pattern for ARMBrcond, but can't use
 | 
			
		||||
  // a two-value operand where a dag node expects two operands. :( 
 | 
			
		||||
  def Bcc : ABI<0b1010, (outs), (ins brtarget:$target),
 | 
			
		||||
               "b", " $target",
 | 
			
		||||
               IIC_Br, "b", " $target",
 | 
			
		||||
               [/*(ARMbrcond bb:$target, imm:$cc, CCR:$ccr)*/]>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -730,132 +732,139 @@ let isBranch = 1, isTerminator = 1, Itinerary = IIC_Br in {
 | 
			
		|||
 | 
			
		||||
// Load
 | 
			
		||||
let canFoldAsLoad = 1 in 
 | 
			
		||||
def LDR  : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
 | 
			
		||||
def LDR  : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad,
 | 
			
		||||
               "ldr", " $dst, $addr",
 | 
			
		||||
               [(set GPR:$dst, (load addrmode2:$addr))]>;
 | 
			
		||||
 | 
			
		||||
// Special LDR for loads from non-pc-relative constpools.
 | 
			
		||||
let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
 | 
			
		||||
def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
 | 
			
		||||
def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad,
 | 
			
		||||
                 "ldr", " $dst, $addr", []>;
 | 
			
		||||
 | 
			
		||||
// Loads with zero extension
 | 
			
		||||
def LDRH  : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
 | 
			
		||||
def LDRH  : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad,
 | 
			
		||||
                 "ldr", "h $dst, $addr",
 | 
			
		||||
                [(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
 | 
			
		||||
 | 
			
		||||
def LDRB  : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
 | 
			
		||||
def LDRB  : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoad,
 | 
			
		||||
                 "ldr", "b $dst, $addr",
 | 
			
		||||
                [(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
 | 
			
		||||
 | 
			
		||||
// Loads with sign extension
 | 
			
		||||
def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
 | 
			
		||||
def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad,
 | 
			
		||||
                 "ldr", "sh $dst, $addr",
 | 
			
		||||
                [(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
 | 
			
		||||
 | 
			
		||||
def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
 | 
			
		||||
def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad,
 | 
			
		||||
                 "ldr", "sb $dst, $addr",
 | 
			
		||||
                [(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
 | 
			
		||||
 | 
			
		||||
let mayLoad = 1 in {
 | 
			
		||||
// Load doubleword
 | 
			
		||||
def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
 | 
			
		||||
                "ldr", "d $dst1, $addr", []>, Requires<[IsARM, HasV5T]>;
 | 
			
		||||
                IIC_iLoad, "ldr", "d $dst1, $addr", []>, Requires<[IsARM, HasV5T]>;
 | 
			
		||||
 | 
			
		||||
// Indexed loads
 | 
			
		||||
def LDR_PRE  : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                     (ins addrmode2:$addr), LdFrm,
 | 
			
		||||
                     (ins addrmode2:$addr), LdFrm, IIC_iLoad,
 | 
			
		||||
                     "ldr", " $dst, $addr!", "$addr.base = $base_wb", []>;
 | 
			
		||||
 | 
			
		||||
def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                     (ins GPR:$base, am2offset:$offset), LdFrm,
 | 
			
		||||
                     (ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoad,
 | 
			
		||||
                     "ldr", " $dst, [$base], $offset", "$base = $base_wb", []>;
 | 
			
		||||
 | 
			
		||||
def LDRH_PRE  : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                     (ins addrmode3:$addr), LdMiscFrm,
 | 
			
		||||
                     (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad,
 | 
			
		||||
                     "ldr", "h $dst, $addr!", "$addr.base = $base_wb", []>;
 | 
			
		||||
 | 
			
		||||
def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                     (ins GPR:$base,am3offset:$offset), LdMiscFrm,
 | 
			
		||||
                     (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad,
 | 
			
		||||
                     "ldr", "h $dst, [$base], $offset", "$base = $base_wb", []>;
 | 
			
		||||
 | 
			
		||||
def LDRB_PRE  : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                     (ins addrmode2:$addr), LdFrm,
 | 
			
		||||
                     (ins addrmode2:$addr), LdFrm, IIC_iLoad,
 | 
			
		||||
                     "ldr", "b $dst, $addr!", "$addr.base = $base_wb", []>;
 | 
			
		||||
 | 
			
		||||
def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                     (ins GPR:$base,am2offset:$offset), LdFrm,
 | 
			
		||||
                     (ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoad,
 | 
			
		||||
                     "ldr", "b $dst, [$base], $offset", "$base = $base_wb", []>;
 | 
			
		||||
 | 
			
		||||
def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                      (ins addrmode3:$addr), LdMiscFrm,
 | 
			
		||||
                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad,
 | 
			
		||||
                      "ldr", "sh $dst, $addr!", "$addr.base = $base_wb", []>;
 | 
			
		||||
 | 
			
		||||
def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                      (ins GPR:$base,am3offset:$offset), LdMiscFrm,
 | 
			
		||||
                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad,
 | 
			
		||||
                    "ldr", "sh $dst, [$base], $offset", "$base = $base_wb", []>;
 | 
			
		||||
 | 
			
		||||
def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                      (ins addrmode3:$addr), LdMiscFrm,
 | 
			
		||||
                      (ins addrmode3:$addr), LdMiscFrm, IIC_iLoad,
 | 
			
		||||
                      "ldr", "sb $dst, $addr!", "$addr.base = $base_wb", []>;
 | 
			
		||||
 | 
			
		||||
def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                      (ins GPR:$base,am3offset:$offset), LdMiscFrm,
 | 
			
		||||
                      (ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoad,
 | 
			
		||||
                    "ldr", "sb $dst, [$base], $offset", "$base = $base_wb", []>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Store
 | 
			
		||||
def STR  : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
 | 
			
		||||
def STR  : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStore,
 | 
			
		||||
               "str", " $src, $addr",
 | 
			
		||||
               [(store GPR:$src, addrmode2:$addr)]>;
 | 
			
		||||
 | 
			
		||||
// Stores with truncate
 | 
			
		||||
def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
 | 
			
		||||
def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm, IIC_iStore,
 | 
			
		||||
               "str", "h $src, $addr",
 | 
			
		||||
               [(truncstorei16 GPR:$src, addrmode3:$addr)]>;
 | 
			
		||||
 | 
			
		||||
def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm,
 | 
			
		||||
def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStore,
 | 
			
		||||
               "str", "b $src, $addr",
 | 
			
		||||
               [(truncstorei8 GPR:$src, addrmode2:$addr)]>;
 | 
			
		||||
 | 
			
		||||
// Store doubleword
 | 
			
		||||
let mayStore = 1 in
 | 
			
		||||
def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),StMiscFrm,
 | 
			
		||||
def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
 | 
			
		||||
               StMiscFrm, IIC_iStore,
 | 
			
		||||
               "str", "d $src1, $addr", []>, Requires<[IsARM, HasV5T]>;
 | 
			
		||||
 | 
			
		||||
// Indexed stores
 | 
			
		||||
def STR_PRE  : AI2stwpr<(outs GPR:$base_wb),
 | 
			
		||||
                     (ins GPR:$src, GPR:$base, am2offset:$offset), StFrm,
 | 
			
		||||
                     (ins GPR:$src, GPR:$base, am2offset:$offset), 
 | 
			
		||||
                     StFrm, IIC_iStore,
 | 
			
		||||
                    "str", " $src, [$base, $offset]!", "$base = $base_wb",
 | 
			
		||||
                    [(set GPR:$base_wb,
 | 
			
		||||
                      (pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
 | 
			
		||||
 | 
			
		||||
def STR_POST : AI2stwpo<(outs GPR:$base_wb),
 | 
			
		||||
                     (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
 | 
			
		||||
                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
 | 
			
		||||
                     StFrm, IIC_iStore,
 | 
			
		||||
                    "str", " $src, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
                    [(set GPR:$base_wb,
 | 
			
		||||
                      (post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
 | 
			
		||||
 | 
			
		||||
def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
 | 
			
		||||
                     (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
 | 
			
		||||
                     (ins GPR:$src, GPR:$base,am3offset:$offset), 
 | 
			
		||||
                     StMiscFrm, IIC_iStore,
 | 
			
		||||
                     "str", "h $src, [$base, $offset]!", "$base = $base_wb",
 | 
			
		||||
                    [(set GPR:$base_wb,
 | 
			
		||||
                      (pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
 | 
			
		||||
 | 
			
		||||
def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
 | 
			
		||||
                     (ins GPR:$src, GPR:$base,am3offset:$offset), StMiscFrm,
 | 
			
		||||
                     (ins GPR:$src, GPR:$base,am3offset:$offset), 
 | 
			
		||||
                     StMiscFrm, IIC_iStore,
 | 
			
		||||
                     "str", "h $src, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
                    [(set GPR:$base_wb, (post_truncsti16 GPR:$src,
 | 
			
		||||
                                         GPR:$base, am3offset:$offset))]>;
 | 
			
		||||
 | 
			
		||||
def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
 | 
			
		||||
                     (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
 | 
			
		||||
                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
 | 
			
		||||
                     StFrm, IIC_iStore,
 | 
			
		||||
                     "str", "b $src, [$base, $offset]!", "$base = $base_wb",
 | 
			
		||||
                    [(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
 | 
			
		||||
                                         GPR:$base, am2offset:$offset))]>;
 | 
			
		||||
 | 
			
		||||
def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
 | 
			
		||||
                     (ins GPR:$src, GPR:$base,am2offset:$offset), StFrm,
 | 
			
		||||
                     (ins GPR:$src, GPR:$base,am2offset:$offset), 
 | 
			
		||||
                     StFrm, IIC_iStore,
 | 
			
		||||
                     "str", "b $src, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
                    [(set GPR:$base_wb, (post_truncsti8 GPR:$src,
 | 
			
		||||
                                         GPR:$base, am2offset:$offset))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -868,13 +877,13 @@ def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
 | 
			
		|||
let mayLoad = 1 in
 | 
			
		||||
def LDM : AXI4ld<(outs),
 | 
			
		||||
               (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
 | 
			
		||||
               LdStMulFrm, "ldm${p}${addr:submode} $addr, $dst1",
 | 
			
		||||
               LdStMulFrm, IIC_iLoad, "ldm${p}${addr:submode} $addr, $dst1",
 | 
			
		||||
               []>;
 | 
			
		||||
 | 
			
		||||
let mayStore = 1 in
 | 
			
		||||
def STM : AXI4st<(outs),
 | 
			
		||||
               (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops),
 | 
			
		||||
               LdStMulFrm, "stm${p}${addr:submode} $addr, $src1",
 | 
			
		||||
               LdStMulFrm, IIC_iStore, "stm${p}${addr:submode} $addr, $src1",
 | 
			
		||||
               []>;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			@ -882,16 +891,17 @@ def STM : AXI4st<(outs),
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
let neverHasSideEffects = 1 in
 | 
			
		||||
def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm,
 | 
			
		||||
def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iALU,
 | 
			
		||||
                 "mov", " $dst, $src", []>, UnaryDP;
 | 
			
		||||
def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
 | 
			
		||||
def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src), 
 | 
			
		||||
                 DPSoRegFrm, IIC_iALU,
 | 
			
		||||
                 "mov", " $dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP;
 | 
			
		||||
 | 
			
		||||
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
 | 
			
		||||
def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm,
 | 
			
		||||
def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iALU,
 | 
			
		||||
                 "mov", " $dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP;
 | 
			
		||||
 | 
			
		||||
def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
 | 
			
		||||
def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iALU,
 | 
			
		||||
                 "mov", " $dst, $src, rrx",
 | 
			
		||||
                 [(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -900,10 +910,10 @@ def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
 | 
			
		|||
 | 
			
		||||
let Defs = [CPSR] in {
 | 
			
		||||
def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, 
 | 
			
		||||
                      "mov", "s $dst, $src, lsr #1",
 | 
			
		||||
                      IIC_iALU, "mov", "s $dst, $src, lsr #1",
 | 
			
		||||
                      [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
 | 
			
		||||
def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
 | 
			
		||||
                      "mov", "s $dst, $src, asr #1",
 | 
			
		||||
                      IIC_iALU, "mov", "s $dst, $src, asr #1",
 | 
			
		||||
                      [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -973,30 +983,30 @@ defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
 | 
			
		|||
 | 
			
		||||
// These don't define reg/reg forms, because they are handled above.
 | 
			
		||||
def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
 | 
			
		||||
                  "rsb", " $dst, $a, $b",
 | 
			
		||||
                  IIC_iALU, "rsb", " $dst, $a, $b",
 | 
			
		||||
                  [(set GPR:$dst, (sub so_imm:$b, GPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
 | 
			
		||||
                  "rsb", " $dst, $a, $b",
 | 
			
		||||
                  IIC_iALU, "rsb", " $dst, $a, $b",
 | 
			
		||||
                  [(set GPR:$dst, (sub so_reg:$b, GPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
// RSB with 's' bit set.
 | 
			
		||||
let Defs = [CPSR] in {
 | 
			
		||||
def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
 | 
			
		||||
                 "rsb", "s $dst, $a, $b",
 | 
			
		||||
                 IIC_iALU, "rsb", "s $dst, $a, $b",
 | 
			
		||||
                 [(set GPR:$dst, (subc so_imm:$b, GPR:$a))]>;
 | 
			
		||||
def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
 | 
			
		||||
                 "rsb", "s $dst, $a, $b",
 | 
			
		||||
                 IIC_iALU, "rsb", "s $dst, $a, $b",
 | 
			
		||||
                 [(set GPR:$dst, (subc so_reg:$b, GPR:$a))]>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let Uses = [CPSR] in {
 | 
			
		||||
def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
 | 
			
		||||
                 DPFrm, "rsc", " $dst, $a, $b",
 | 
			
		||||
                 DPFrm, IIC_iALU, "rsc", " $dst, $a, $b",
 | 
			
		||||
                 [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
 | 
			
		||||
                 Requires<[IsARM, CarryDefIsUnused]>;
 | 
			
		||||
def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
 | 
			
		||||
                 DPSoRegFrm, "rsc", " $dst, $a, $b",
 | 
			
		||||
                 DPSoRegFrm, IIC_iALU, "rsc", " $dst, $a, $b",
 | 
			
		||||
                 [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
 | 
			
		||||
                 Requires<[IsARM, CarryDefIsUnused]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1004,11 +1014,11 @@ def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
 | 
			
		|||
// FIXME: Allow these to be predicated.
 | 
			
		||||
let Defs = [CPSR], Uses = [CPSR] in {
 | 
			
		||||
def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
 | 
			
		||||
                  DPFrm, "rscs $dst, $a, $b",
 | 
			
		||||
                  DPFrm, IIC_iALU, "rscs $dst, $a, $b",
 | 
			
		||||
                  [(set GPR:$dst, (sube so_imm:$b, GPR:$a))]>,
 | 
			
		||||
                  Requires<[IsARM, CarryDefIsUnused]>;
 | 
			
		||||
def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
 | 
			
		||||
                  DPSoRegFrm, "rscs $dst, $a, $b",
 | 
			
		||||
                  DPSoRegFrm, IIC_iALU, "rscs $dst, $a, $b",
 | 
			
		||||
                  [(set GPR:$dst, (sube so_reg:$b, GPR:$a))]>,
 | 
			
		||||
                  Requires<[IsARM, CarryDefIsUnused]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1043,7 +1053,7 @@ defm BIC   : AsI1_bin_irs<0b1110, "bic",
 | 
			
		|||
                          BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
 | 
			
		||||
 | 
			
		||||
def BFC    : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
 | 
			
		||||
               AddrMode1, Size4Bytes, IndexModeNone, DPFrm,
 | 
			
		||||
               AddrMode1, Size4Bytes, IndexModeNone, DPFrm, NoItinerary,
 | 
			
		||||
               "bfc", " $dst, $imm", "$src = $dst",
 | 
			
		||||
               [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
 | 
			
		||||
               Requires<[IsARM, HasV6T2]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1051,14 +1061,14 @@ def BFC    : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
 | 
			
		|||
  let Inst{6-0}   = 0b0011111;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def  MVNr  : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm,
 | 
			
		||||
def  MVNr  : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iALU,
 | 
			
		||||
                  "mvn", " $dst, $src",
 | 
			
		||||
                  [(set GPR:$dst, (not GPR:$src))]>, UnaryDP;
 | 
			
		||||
def  MVNs  : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
 | 
			
		||||
                  "mvn", " $dst, $src",
 | 
			
		||||
                  IIC_iALU, "mvn", " $dst, $src",
 | 
			
		||||
                  [(set GPR:$dst, (not so_reg:$src))]>, UnaryDP;
 | 
			
		||||
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
 | 
			
		||||
def  MVNi  : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
 | 
			
		||||
def  MVNi  : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm, IIC_iALU,
 | 
			
		||||
                  "mvn", " $dst, $imm",
 | 
			
		||||
                  [(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1070,16 +1080,16 @@ def : ARMPat<(and   GPR:$src, so_imm_not:$imm),
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
let isCommutable = 1 in
 | 
			
		||||
def MUL   : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
def MUL   : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                    "mul", " $dst, $a, $b",
 | 
			
		||||
                   [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
 | 
			
		||||
 | 
			
		||||
def MLA   : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		||||
                    "mla", " $dst, $a, $b, $c",
 | 
			
		||||
                    IIC_iALU, "mla", " $dst, $a, $b, $c",
 | 
			
		||||
                   [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
 | 
			
		||||
 | 
			
		||||
def MLS   : AMul1I <0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		||||
                    "mls", " $dst, $a, $b, $c",
 | 
			
		||||
def MLS   : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		||||
                   IIC_iALU, "mls", " $dst, $a, $b, $c",
 | 
			
		||||
                   [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
 | 
			
		||||
                   Requires<[IsARM, HasV6T2]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1087,32 +1097,32 @@ def MLS   : AMul1I <0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		|||
let neverHasSideEffects = 1 in {
 | 
			
		||||
let isCommutable = 1 in {
 | 
			
		||||
def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
 | 
			
		||||
                               (ins GPR:$a, GPR:$b),
 | 
			
		||||
                               (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                    "smull", " $ldst, $hdst, $a, $b", []>;
 | 
			
		||||
 | 
			
		||||
def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
 | 
			
		||||
                               (ins GPR:$a, GPR:$b),
 | 
			
		||||
                               (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                    "umull", " $ldst, $hdst, $a, $b", []>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Multiply + accumulate
 | 
			
		||||
def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
 | 
			
		||||
                               (ins GPR:$a, GPR:$b),
 | 
			
		||||
                               (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                    "smlal", " $ldst, $hdst, $a, $b", []>;
 | 
			
		||||
 | 
			
		||||
def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
 | 
			
		||||
                               (ins GPR:$a, GPR:$b),
 | 
			
		||||
                               (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                    "umlal", " $ldst, $hdst, $a, $b", []>;
 | 
			
		||||
 | 
			
		||||
def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
 | 
			
		||||
                               (ins GPR:$a, GPR:$b),
 | 
			
		||||
                               (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                    "umaal", " $ldst, $hdst, $a, $b", []>,
 | 
			
		||||
                    Requires<[IsARM, HasV6]>;
 | 
			
		||||
} // neverHasSideEffects
 | 
			
		||||
 | 
			
		||||
// Most significant word multiply
 | 
			
		||||
def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
               "smmul", " $dst, $a, $b",
 | 
			
		||||
               IIC_iALU, "smmul", " $dst, $a, $b",
 | 
			
		||||
               [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
 | 
			
		||||
            Requires<[IsARM, HasV6]> {
 | 
			
		||||
  let Inst{7-4}   = 0b0001;
 | 
			
		||||
| 
						 | 
				
			
			@ -1120,7 +1130,7 @@ def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		||||
               "smmla", " $dst, $a, $b, $c",
 | 
			
		||||
               IIC_iALU, "smmla", " $dst, $a, $b, $c",
 | 
			
		||||
               [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
 | 
			
		||||
            Requires<[IsARM, HasV6]> {
 | 
			
		||||
  let Inst{7-4}   = 0b0001;
 | 
			
		||||
| 
						 | 
				
			
			@ -1128,7 +1138,7 @@ def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		||||
               "smmls", " $dst, $a, $b, $c",
 | 
			
		||||
               IIC_iALU, "smmls", " $dst, $a, $b, $c",
 | 
			
		||||
               [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
 | 
			
		||||
            Requires<[IsARM, HasV6]> {
 | 
			
		||||
  let Inst{7-4}   = 0b1101;
 | 
			
		||||
| 
						 | 
				
			
			@ -1136,7 +1146,7 @@ def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		|||
 | 
			
		||||
multiclass AI_smul<string opc, PatFrag opnode> {
 | 
			
		||||
  def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
              !strconcat(opc, "bb"), " $dst, $a, $b",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "bb"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
 | 
			
		||||
                                      (sext_inreg GPR:$b, i16)))]>,
 | 
			
		||||
           Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1145,7 +1155,7 @@ multiclass AI_smul<string opc, PatFrag opnode> {
 | 
			
		|||
           }
 | 
			
		||||
 | 
			
		||||
  def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
              !strconcat(opc, "bt"), " $dst, $a, $b",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "bt"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
 | 
			
		||||
                                      (sra GPR:$b, (i32 16))))]>,
 | 
			
		||||
           Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1154,7 +1164,7 @@ multiclass AI_smul<string opc, PatFrag opnode> {
 | 
			
		|||
           }
 | 
			
		||||
 | 
			
		||||
  def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
              !strconcat(opc, "tb"), " $dst, $a, $b",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "tb"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
 | 
			
		||||
                                      (sext_inreg GPR:$b, i16)))]>,
 | 
			
		||||
           Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1163,7 +1173,7 @@ multiclass AI_smul<string opc, PatFrag opnode> {
 | 
			
		|||
           }
 | 
			
		||||
 | 
			
		||||
  def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
              !strconcat(opc, "tt"), " $dst, $a, $b",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "tt"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
 | 
			
		||||
                                      (sra GPR:$b, (i32 16))))]>,
 | 
			
		||||
            Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1172,7 +1182,7 @@ multiclass AI_smul<string opc, PatFrag opnode> {
 | 
			
		|||
           }
 | 
			
		||||
 | 
			
		||||
  def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
              !strconcat(opc, "wb"), " $dst, $a, $b",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "wb"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (sra (opnode GPR:$a,
 | 
			
		||||
                                    (sext_inreg GPR:$b, i16)), (i32 16)))]>,
 | 
			
		||||
           Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1181,7 +1191,7 @@ multiclass AI_smul<string opc, PatFrag opnode> {
 | 
			
		|||
           }
 | 
			
		||||
 | 
			
		||||
  def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
              !strconcat(opc, "wt"), " $dst, $a, $b",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "wt"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (sra (opnode GPR:$a,
 | 
			
		||||
                                    (sra GPR:$b, (i32 16))), (i32 16)))]>,
 | 
			
		||||
            Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1193,7 +1203,7 @@ multiclass AI_smul<string opc, PatFrag opnode> {
 | 
			
		|||
 | 
			
		||||
multiclass AI_smla<string opc, PatFrag opnode> {
 | 
			
		||||
  def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
              !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
 | 
			
		||||
              [(set GPR:$dst, (add GPR:$acc,
 | 
			
		||||
                               (opnode (sext_inreg GPR:$a, i16),
 | 
			
		||||
                                       (sext_inreg GPR:$b, i16))))]>,
 | 
			
		||||
| 
						 | 
				
			
			@ -1203,7 +1213,7 @@ multiclass AI_smla<string opc, PatFrag opnode> {
 | 
			
		|||
           }
 | 
			
		||||
 | 
			
		||||
  def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
              !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
 | 
			
		||||
              [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
 | 
			
		||||
                                                     (sra GPR:$b, (i32 16)))))]>,
 | 
			
		||||
           Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1212,7 +1222,7 @@ multiclass AI_smla<string opc, PatFrag opnode> {
 | 
			
		|||
           }
 | 
			
		||||
 | 
			
		||||
  def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
              !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
 | 
			
		||||
              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
 | 
			
		||||
                                                 (sext_inreg GPR:$b, i16))))]>,
 | 
			
		||||
           Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1221,7 +1231,7 @@ multiclass AI_smla<string opc, PatFrag opnode> {
 | 
			
		|||
           }
 | 
			
		||||
 | 
			
		||||
  def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
              !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
 | 
			
		||||
              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
 | 
			
		||||
                                                     (sra GPR:$b, (i32 16)))))]>,
 | 
			
		||||
            Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1230,7 +1240,7 @@ multiclass AI_smla<string opc, PatFrag opnode> {
 | 
			
		|||
           }
 | 
			
		||||
 | 
			
		||||
  def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
              !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
 | 
			
		||||
              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
 | 
			
		||||
                                       (sext_inreg GPR:$b, i16)), (i32 16))))]>,
 | 
			
		||||
           Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1239,7 +1249,7 @@ multiclass AI_smla<string opc, PatFrag opnode> {
 | 
			
		|||
           }
 | 
			
		||||
 | 
			
		||||
  def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
              !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
 | 
			
		||||
              IIC_iALU, !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
 | 
			
		||||
              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
 | 
			
		||||
                                         (sra GPR:$b, (i32 16))), (i32 16))))]>,
 | 
			
		||||
            Requires<[IsARM, HasV5TE]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1258,7 +1268,7 @@ defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
 | 
			
		|||
//  Misc. Arithmetic Instructions.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
def CLZ  : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def CLZ  : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
              "clz", " $dst, $src",
 | 
			
		||||
              [(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
 | 
			
		||||
  let Inst{7-4}   = 0b0001;
 | 
			
		||||
| 
						 | 
				
			
			@ -1266,7 +1276,7 @@ def CLZ  : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src),
 | 
			
		|||
  let Inst{19-16} = 0b1111;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def REV  : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def REV  : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
              "rev", " $dst, $src",
 | 
			
		||||
              [(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
 | 
			
		||||
  let Inst{7-4}   = 0b0011;
 | 
			
		||||
| 
						 | 
				
			
			@ -1274,7 +1284,7 @@ def REV  : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
 | 
			
		|||
  let Inst{19-16} = 0b1111;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
               "rev16", " $dst, $src",
 | 
			
		||||
               [(set GPR:$dst,
 | 
			
		||||
                   (or (and (srl GPR:$src, (i32 8)), 0xFF),
 | 
			
		||||
| 
						 | 
				
			
			@ -1287,7 +1297,7 @@ def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src),
 | 
			
		|||
  let Inst{19-16} = 0b1111;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
               "revsh", " $dst, $src",
 | 
			
		||||
               [(set GPR:$dst,
 | 
			
		||||
                  (sext_inreg
 | 
			
		||||
| 
						 | 
				
			
			@ -1301,7 +1311,7 @@ def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src),
 | 
			
		|||
 | 
			
		||||
def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
 | 
			
		||||
                                 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
 | 
			
		||||
               "pkhbt", " $dst, $src1, $src2, LSL $shamt",
 | 
			
		||||
               IIC_iALU, "pkhbt", " $dst, $src1, $src2, LSL $shamt",
 | 
			
		||||
               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
 | 
			
		||||
                                   (and (shl GPR:$src2, (i32 imm:$shamt)),
 | 
			
		||||
                                        0xFFFF0000)))]>,
 | 
			
		||||
| 
						 | 
				
			
			@ -1318,7 +1328,7 @@ def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
 | 
			
		|||
 | 
			
		||||
def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
 | 
			
		||||
                                 (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
 | 
			
		||||
               "pkhtb", " $dst, $src1, $src2, ASR $shamt",
 | 
			
		||||
               IIC_iALU, "pkhtb", " $dst, $src1, $src2, ASR $shamt",
 | 
			
		||||
               [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
 | 
			
		||||
                                   (and (sra GPR:$src2, imm16_31:$shamt),
 | 
			
		||||
                                        0xFFFF)))]>, Requires<[IsARM, HasV6]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -1364,18 +1374,18 @@ def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
 | 
			
		|||
// FIXME: should be able to write a pattern for ARMcmov, but can't use
 | 
			
		||||
// a two-value operand where a dag node expects two operands. :( 
 | 
			
		||||
def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
 | 
			
		||||
                "mov", " $dst, $true",
 | 
			
		||||
                IIC_iALU, "mov", " $dst, $true",
 | 
			
		||||
      [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
 | 
			
		||||
                RegConstraint<"$false = $dst">, UnaryDP;
 | 
			
		||||
 | 
			
		||||
def MOVCCs : AI1<0b1101, (outs GPR:$dst),
 | 
			
		||||
                        (ins GPR:$false, so_reg:$true), DPSoRegFrm,
 | 
			
		||||
                        (ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iALU,
 | 
			
		||||
                "mov", " $dst, $true",
 | 
			
		||||
   [/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
 | 
			
		||||
                RegConstraint<"$false = $dst">, UnaryDP;
 | 
			
		||||
 | 
			
		||||
def MOVCCi : AI1<0b1101, (outs GPR:$dst),
 | 
			
		||||
                        (ins GPR:$false, so_imm:$true), DPFrm,
 | 
			
		||||
                        (ins GPR:$false, so_imm:$true), DPFrm, IIC_iALU,
 | 
			
		||||
                "mov", " $dst, $true",
 | 
			
		||||
   [/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
 | 
			
		||||
                RegConstraint<"$false = $dst">, UnaryDP;
 | 
			
		||||
| 
						 | 
				
			
			@ -1388,7 +1398,7 @@ def MOVCCi : AI1<0b1101, (outs GPR:$dst),
 | 
			
		|||
// __aeabi_read_tp preserves the registers r1-r3.
 | 
			
		||||
let isCall = 1,
 | 
			
		||||
  Defs = [R0, R12, LR, CPSR] in {
 | 
			
		||||
  def TPsoft : ABXI<0b1011, (outs), (ins),
 | 
			
		||||
  def TPsoft : ABXI<0b1011, (outs), (ins), IIC_Br,
 | 
			
		||||
               "bl __aeabi_read_tp",
 | 
			
		||||
               [(set R0, ARMthread_pointer)]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1411,7 +1421,8 @@ let Defs =
 | 
			
		|||
    D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
 | 
			
		||||
    D31 ] in {
 | 
			
		||||
  def Int_eh_sjlj_setjmp : XI<(outs), (ins GPR:$src),
 | 
			
		||||
                               AddrModeNone, SizeSpecial, IndexModeNone, Pseudo,
 | 
			
		||||
                               AddrModeNone, SizeSpecial, IndexModeNone,
 | 
			
		||||
                               Pseudo, NoItinerary,
 | 
			
		||||
                               "add r0, pc, #4\n\t"
 | 
			
		||||
                               "str r0, [$src, #+4]\n\t"
 | 
			
		||||
                               "mov r0, #0 @ eh_setjmp", "",
 | 
			
		||||
| 
						 | 
				
			
			@ -1432,7 +1443,8 @@ def : ARMPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
 | 
			
		|||
 | 
			
		||||
// Two piece so_imms.
 | 
			
		||||
let isReMaterializable = 1 in
 | 
			
		||||
def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), Pseudo,
 | 
			
		||||
def MOVi2pieces : AI1x2<(outs GPR:$dst), (ins so_imm2part:$src), 
 | 
			
		||||
                         Pseudo, IIC_iALU,
 | 
			
		||||
                         "mov", " $dst, $src",
 | 
			
		||||
                         [(set GPR:$dst, so_imm2part:$src)]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -103,6 +103,7 @@ def addrmode_neonldstm : Operand<i32>,
 | 
			
		|||
let mayLoad = 1 in {
 | 
			
		||||
def VLDMD : NI<(outs),
 | 
			
		||||
               (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops),
 | 
			
		||||
               NoItinerary,
 | 
			
		||||
               "vldm${addr:submode} ${addr:base}, $dst1",
 | 
			
		||||
               []> {
 | 
			
		||||
  let Inst{27-25} = 0b110;
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +113,7 @@ def VLDMD : NI<(outs),
 | 
			
		|||
 | 
			
		||||
def VLDMS : NI<(outs),
 | 
			
		||||
               (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops),
 | 
			
		||||
               NoItinerary,
 | 
			
		||||
               "vldm${addr:submode} ${addr:base}, $dst1",
 | 
			
		||||
               []> {
 | 
			
		||||
  let Inst{27-25} = 0b110;
 | 
			
		||||
| 
						 | 
				
			
			@ -123,6 +125,7 @@ def VLDMS : NI<(outs),
 | 
			
		|||
 | 
			
		||||
// Use vldmia to load a Q register as a D register pair.
 | 
			
		||||
def VLDRQ : NI<(outs QPR:$dst), (ins GPR:$addr),
 | 
			
		||||
               NoItinerary,
 | 
			
		||||
               "vldmia $addr, ${dst:dregpair}",
 | 
			
		||||
               [(set QPR:$dst, (v2f64 (load GPR:$addr)))]> {
 | 
			
		||||
  let Inst{27-25} = 0b110;
 | 
			
		||||
| 
						 | 
				
			
			@ -134,6 +137,7 @@ def VLDRQ : NI<(outs QPR:$dst), (ins GPR:$addr),
 | 
			
		|||
 | 
			
		||||
// Use vstmia to store a Q register as a D register pair.
 | 
			
		||||
def VSTRQ : NI<(outs), (ins QPR:$src, GPR:$addr),
 | 
			
		||||
               NoItinerary,
 | 
			
		||||
               "vstmia $addr, ${src:dregpair}",
 | 
			
		||||
               [(store (v2f64 QPR:$src), GPR:$addr)]> {
 | 
			
		||||
  let Inst{27-25} = 0b110;
 | 
			
		||||
| 
						 | 
				
			
			@ -147,10 +151,12 @@ def VSTRQ : NI<(outs), (ins QPR:$src, GPR:$addr),
 | 
			
		|||
//   VLD1     : Vector Load (multiple single elements)
 | 
			
		||||
class VLD1D<string OpcodeStr, ValueType Ty, Intrinsic IntOp>
 | 
			
		||||
  : NLdSt<(outs DPR:$dst), (ins addrmode6:$addr),
 | 
			
		||||
          NoItinerary,
 | 
			
		||||
          !strconcat(OpcodeStr, "\t\\{$dst\\}, $addr"),
 | 
			
		||||
          [(set DPR:$dst, (Ty (IntOp addrmode6:$addr)))]>;
 | 
			
		||||
class VLD1Q<string OpcodeStr, ValueType Ty, Intrinsic IntOp>
 | 
			
		||||
  : NLdSt<(outs QPR:$dst), (ins addrmode6:$addr),
 | 
			
		||||
          NoItinerary,
 | 
			
		||||
          !strconcat(OpcodeStr, "\t${dst:dregpair}, $addr"),
 | 
			
		||||
          [(set QPR:$dst, (Ty (IntOp addrmode6:$addr)))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -169,10 +175,12 @@ def  VLD1q64  : VLD1Q<"vld1.64", v2i64, int_arm_neon_vld1i>;
 | 
			
		|||
//   VST1     : Vector Store (multiple single elements)
 | 
			
		||||
class VST1D<string OpcodeStr, ValueType Ty, Intrinsic IntOp>
 | 
			
		||||
  : NLdSt<(outs), (ins addrmode6:$addr, DPR:$src),
 | 
			
		||||
          NoItinerary,
 | 
			
		||||
          !strconcat(OpcodeStr, "\t\\{$src\\}, $addr"),
 | 
			
		||||
          [(IntOp addrmode6:$addr, (Ty DPR:$src))]>;
 | 
			
		||||
class VST1Q<string OpcodeStr, ValueType Ty, Intrinsic IntOp>
 | 
			
		||||
  : NLdSt<(outs), (ins addrmode6:$addr, QPR:$src),
 | 
			
		||||
          NoItinerary,
 | 
			
		||||
          !strconcat(OpcodeStr, "\t${src:dregpair}, $addr"),
 | 
			
		||||
          [(IntOp addrmode6:$addr, (Ty QPR:$src))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -191,6 +199,7 @@ def  VST1q64  : VST1Q<"vst1.64", v2i64, int_arm_neon_vst1i>;
 | 
			
		|||
//   VLD2     : Vector Load (multiple 2-element structures)
 | 
			
		||||
class VLD2D<string OpcodeStr>
 | 
			
		||||
  : NLdSt<(outs DPR:$dst1, DPR:$dst2), (ins addrmode6:$addr),
 | 
			
		||||
          NoItinerary,
 | 
			
		||||
          !strconcat(OpcodeStr, "\t\\{$dst1,$dst2\\}, $addr"), []>;
 | 
			
		||||
 | 
			
		||||
def  VLD2d8   : VLD2D<"vld2.8">;
 | 
			
		||||
| 
						 | 
				
			
			@ -200,6 +209,7 @@ def  VLD2d32  : VLD2D<"vld2.32">;
 | 
			
		|||
//   VLD3     : Vector Load (multiple 3-element structures)
 | 
			
		||||
class VLD3D<string OpcodeStr>
 | 
			
		||||
  : NLdSt<(outs DPR:$dst1, DPR:$dst2, DPR:$dst3), (ins addrmode6:$addr),
 | 
			
		||||
          NoItinerary,
 | 
			
		||||
          !strconcat(OpcodeStr, "\t\\{$dst1,$dst2,$dst3\\}, $addr"), []>;
 | 
			
		||||
 | 
			
		||||
def  VLD3d8   : VLD3D<"vld3.8">;
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +220,7 @@ def  VLD3d32  : VLD3D<"vld3.32">;
 | 
			
		|||
class VLD4D<string OpcodeStr>
 | 
			
		||||
  : NLdSt<(outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4),
 | 
			
		||||
          (ins addrmode6:$addr),
 | 
			
		||||
          NoItinerary,
 | 
			
		||||
          !strconcat(OpcodeStr, "\t\\{$dst1,$dst2,$dst3,$dst4\\}, $addr"), []>;
 | 
			
		||||
 | 
			
		||||
def  VLD4d8   : VLD4D<"vld4.8">;
 | 
			
		||||
| 
						 | 
				
			
			@ -256,13 +267,13 @@ class N2VD<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 | 
			
		|||
           bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 | 
			
		||||
           ValueType ResTy, ValueType OpTy, SDNode OpNode>
 | 
			
		||||
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst),
 | 
			
		||||
        (ins DPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins DPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src))))]>;
 | 
			
		||||
class N2VQ<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 | 
			
		||||
           bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 | 
			
		||||
           ValueType ResTy, ValueType OpTy, SDNode OpNode>
 | 
			
		||||
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst),
 | 
			
		||||
        (ins QPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins QPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src))))]>;
 | 
			
		||||
 | 
			
		||||
// Basic 2-register intrinsics, both double- and quad-register.
 | 
			
		||||
| 
						 | 
				
			
			@ -270,13 +281,13 @@ class N2VDInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 | 
			
		|||
              bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 | 
			
		||||
              ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 | 
			
		||||
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst),
 | 
			
		||||
        (ins DPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins DPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src))))]>;
 | 
			
		||||
class N2VQInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 | 
			
		||||
              bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 | 
			
		||||
              ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 | 
			
		||||
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst),
 | 
			
		||||
        (ins QPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins QPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src))))]>;
 | 
			
		||||
 | 
			
		||||
// Basic 2-register operations, scalar single-precision
 | 
			
		||||
| 
						 | 
				
			
			@ -293,7 +304,7 @@ class N2VNInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 | 
			
		|||
              bits<2> op17_16, bits<5> op11_7, bit op6, bit op4,
 | 
			
		||||
              string OpcodeStr, ValueType TyD, ValueType TyQ, Intrinsic IntOp>
 | 
			
		||||
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, op6, op4, (outs DPR:$dst),
 | 
			
		||||
        (ins QPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins QPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set DPR:$dst, (TyD (IntOp (TyQ QPR:$src))))]>;
 | 
			
		||||
 | 
			
		||||
// Long 2-register intrinsics.  (This is currently only used for VMOVL and is
 | 
			
		||||
| 
						 | 
				
			
			@ -302,7 +313,7 @@ class N2VLInt<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		|||
              bit op6, bit op4, string OpcodeStr, ValueType TyQ, ValueType TyD,
 | 
			
		||||
              Intrinsic IntOp>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, op6, op4, (outs QPR:$dst),
 | 
			
		||||
        (ins DPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins DPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set QPR:$dst, (TyQ (IntOp (TyD DPR:$src))))]>;
 | 
			
		||||
 | 
			
		||||
// Basic 3-register operations, both double- and quad-register.
 | 
			
		||||
| 
						 | 
				
			
			@ -310,7 +321,7 @@ class N3VD<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
           string OpcodeStr, ValueType ResTy, ValueType OpTy,
 | 
			
		||||
           SDNode OpNode, bit Commutable>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2),
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), NoItinerary, 
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "",
 | 
			
		||||
        [(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src1), (OpTy DPR:$src2))))]> {
 | 
			
		||||
  let isCommutable = Commutable;
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +330,7 @@ class N3VQ<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
           string OpcodeStr, ValueType ResTy, ValueType OpTy,
 | 
			
		||||
           SDNode OpNode, bit Commutable>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 1, op4,
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2),
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), NoItinerary, 
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "",
 | 
			
		||||
        [(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src1), (OpTy QPR:$src2))))]> {
 | 
			
		||||
  let isCommutable = Commutable;
 | 
			
		||||
| 
						 | 
				
			
			@ -341,7 +352,7 @@ class N3VDInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
              string OpcodeStr, ValueType ResTy, ValueType OpTy,
 | 
			
		||||
              Intrinsic IntOp, bit Commutable>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2),
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), NoItinerary, 
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "",
 | 
			
		||||
        [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src1), (OpTy DPR:$src2))))]> {
 | 
			
		||||
  let isCommutable = Commutable;
 | 
			
		||||
| 
						 | 
				
			
			@ -350,7 +361,7 @@ class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
              string OpcodeStr, ValueType ResTy, ValueType OpTy,
 | 
			
		||||
              Intrinsic IntOp, bit Commutable>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 1, op4,
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2),
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), NoItinerary, 
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "",
 | 
			
		||||
        [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src1), (OpTy QPR:$src2))))]> {
 | 
			
		||||
  let isCommutable = Commutable;
 | 
			
		||||
| 
						 | 
				
			
			@ -360,14 +371,14 @@ class N3VQInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
class N3VDMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		||||
                string OpcodeStr, ValueType Ty, SDNode MulOp, SDNode OpNode>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3),
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst",
 | 
			
		||||
        [(set DPR:$dst, (Ty (OpNode DPR:$src1,
 | 
			
		||||
                             (Ty (MulOp DPR:$src2, DPR:$src3)))))]>;
 | 
			
		||||
class N3VQMulOp<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		||||
                string OpcodeStr, ValueType Ty, SDNode MulOp, SDNode OpNode>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 1, op4,
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3),
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst",
 | 
			
		||||
        [(set QPR:$dst, (Ty (OpNode QPR:$src1,
 | 
			
		||||
                             (Ty (MulOp QPR:$src2, QPR:$src3)))))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -392,7 +403,7 @@ class N3VDInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
               string OpcodeStr, ValueType ResTy, ValueType OpTy,
 | 
			
		||||
               Intrinsic IntOp>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3),
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, DPR:$src3), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst",
 | 
			
		||||
        [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src1),
 | 
			
		||||
                                      (OpTy DPR:$src2), (OpTy DPR:$src3))))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -400,7 +411,7 @@ class N3VQInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
               string OpcodeStr, ValueType ResTy, ValueType OpTy,
 | 
			
		||||
               Intrinsic IntOp>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 1, op4,
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3),
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, QPR:$src3), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst",
 | 
			
		||||
        [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src1),
 | 
			
		||||
                                      (OpTy QPR:$src2), (OpTy QPR:$src3))))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -410,7 +421,7 @@ class N3VQInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
class N3VLInt3<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		||||
               string OpcodeStr, ValueType TyQ, ValueType TyD, Intrinsic IntOp>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, DPR:$src2, DPR:$src3),
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, DPR:$src2, DPR:$src3), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src2, $src3"), "$src1 = $dst",
 | 
			
		||||
        [(set QPR:$dst,
 | 
			
		||||
          (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$src2), (TyD DPR:$src3))))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -420,7 +431,7 @@ class N3VNInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
              string OpcodeStr, ValueType TyD, ValueType TyQ,
 | 
			
		||||
              Intrinsic IntOp, bit Commutable>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 | 
			
		||||
        (outs DPR:$dst), (ins QPR:$src1, QPR:$src2),
 | 
			
		||||
        (outs DPR:$dst), (ins QPR:$src1, QPR:$src2), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "",
 | 
			
		||||
        [(set DPR:$dst, (TyD (IntOp (TyQ QPR:$src1), (TyQ QPR:$src2))))]> {
 | 
			
		||||
  let isCommutable = Commutable;
 | 
			
		||||
| 
						 | 
				
			
			@ -431,7 +442,7 @@ class N3VLInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
              string OpcodeStr, ValueType TyQ, ValueType TyD,
 | 
			
		||||
              Intrinsic IntOp, bit Commutable>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 | 
			
		||||
        (outs QPR:$dst), (ins DPR:$src1, DPR:$src2),
 | 
			
		||||
        (outs QPR:$dst), (ins DPR:$src1, DPR:$src2), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "",
 | 
			
		||||
        [(set QPR:$dst, (TyQ (IntOp (TyD DPR:$src1), (TyD DPR:$src2))))]> {
 | 
			
		||||
  let isCommutable = Commutable;
 | 
			
		||||
| 
						 | 
				
			
			@ -442,7 +453,7 @@ class N3VWInt<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
 | 
			
		|||
              string OpcodeStr, ValueType TyQ, ValueType TyD,
 | 
			
		||||
              Intrinsic IntOp, bit Commutable>
 | 
			
		||||
  : N3V<op24, op23, op21_20, op11_8, 0, op4,
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, DPR:$src2),
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, DPR:$src2), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src1, $src2"), "",
 | 
			
		||||
        [(set QPR:$dst, (TyQ (IntOp (TyQ QPR:$src1), (TyD DPR:$src2))))]> {
 | 
			
		||||
  let isCommutable = Commutable;
 | 
			
		||||
| 
						 | 
				
			
			@ -453,13 +464,13 @@ class N2VDPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 | 
			
		|||
                bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 | 
			
		||||
                ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 | 
			
		||||
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst),
 | 
			
		||||
        (ins DPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins DPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src))))]>;
 | 
			
		||||
class N2VQPLInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 | 
			
		||||
                bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 | 
			
		||||
                ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 | 
			
		||||
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst),
 | 
			
		||||
        (ins QPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins QPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src))))]>;
 | 
			
		||||
 | 
			
		||||
// Pairwise long 2-register accumulate intrinsics,
 | 
			
		||||
| 
						 | 
				
			
			@ -469,14 +480,14 @@ class N2VDPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 | 
			
		|||
                 bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 | 
			
		||||
                 ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 | 
			
		||||
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4,
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2),
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src1, DPR:$src2), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src2"), "$src1 = $dst",
 | 
			
		||||
        [(set DPR:$dst, (ResTy (IntOp (ResTy DPR:$src1), (OpTy DPR:$src2))))]>;
 | 
			
		||||
class N2VQPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 | 
			
		||||
                 bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr,
 | 
			
		||||
                 ValueType ResTy, ValueType OpTy, Intrinsic IntOp>
 | 
			
		||||
  : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4,
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2),
 | 
			
		||||
        (outs QPR:$dst), (ins QPR:$src1, QPR:$src2), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src2"), "$src1 = $dst",
 | 
			
		||||
        [(set QPR:$dst, (ResTy (IntOp (ResTy QPR:$src1), (OpTy QPR:$src2))))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -485,13 +496,13 @@ class N2VQPLInt2<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18,
 | 
			
		|||
class N2VDSh<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		||||
             bit op4, string OpcodeStr, ValueType Ty, SDNode OpNode>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, 0, op4,
 | 
			
		||||
           (outs DPR:$dst), (ins DPR:$src, i32imm:$SIMM),
 | 
			
		||||
           (outs DPR:$dst), (ins DPR:$src, i32imm:$SIMM), NoItinerary,
 | 
			
		||||
           !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "",
 | 
			
		||||
           [(set DPR:$dst, (Ty (OpNode (Ty DPR:$src), (i32 imm:$SIMM))))]>;
 | 
			
		||||
class N2VQSh<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		||||
             bit op4, string OpcodeStr, ValueType Ty, SDNode OpNode>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, 1, op4,
 | 
			
		||||
           (outs QPR:$dst), (ins QPR:$src, i32imm:$SIMM),
 | 
			
		||||
           (outs QPR:$dst), (ins QPR:$src, i32imm:$SIMM), NoItinerary,
 | 
			
		||||
           !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "",
 | 
			
		||||
           [(set QPR:$dst, (Ty (OpNode (Ty QPR:$src), (i32 imm:$SIMM))))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -500,7 +511,7 @@ class N2VLSh<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		|||
             bit op6, bit op4, string OpcodeStr, ValueType ResTy,
 | 
			
		||||
             ValueType OpTy, SDNode OpNode>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, op6, op4,
 | 
			
		||||
           (outs QPR:$dst), (ins DPR:$src, i32imm:$SIMM),
 | 
			
		||||
           (outs QPR:$dst), (ins DPR:$src, i32imm:$SIMM), NoItinerary,
 | 
			
		||||
           !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "",
 | 
			
		||||
           [(set QPR:$dst, (ResTy (OpNode (OpTy DPR:$src),
 | 
			
		||||
                                          (i32 imm:$SIMM))))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -510,7 +521,7 @@ class N2VNSh<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		|||
             bit op6, bit op4, string OpcodeStr, ValueType ResTy,
 | 
			
		||||
             ValueType OpTy, SDNode OpNode>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, op6, op4,
 | 
			
		||||
           (outs DPR:$dst), (ins QPR:$src, i32imm:$SIMM),
 | 
			
		||||
           (outs DPR:$dst), (ins QPR:$src, i32imm:$SIMM), NoItinerary,
 | 
			
		||||
           !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "",
 | 
			
		||||
           [(set DPR:$dst, (ResTy (OpNode (OpTy QPR:$src),
 | 
			
		||||
                                          (i32 imm:$SIMM))))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -521,6 +532,7 @@ class N2VDShAdd<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		|||
                bit op4, string OpcodeStr, ValueType Ty, SDNode ShOp>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, 0, op4,
 | 
			
		||||
           (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, i32imm:$SIMM),
 | 
			
		||||
           NoItinerary, 
 | 
			
		||||
           !strconcat(OpcodeStr, "\t$dst, $src2, $SIMM"), "$src1 = $dst",
 | 
			
		||||
           [(set DPR:$dst, (Ty (add DPR:$src1,
 | 
			
		||||
                                (Ty (ShOp DPR:$src2, (i32 imm:$SIMM))))))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -528,6 +540,7 @@ class N2VQShAdd<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		|||
                bit op4, string OpcodeStr, ValueType Ty, SDNode ShOp>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, 1, op4,
 | 
			
		||||
           (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, i32imm:$SIMM),
 | 
			
		||||
           NoItinerary, 
 | 
			
		||||
           !strconcat(OpcodeStr, "\t$dst, $src2, $SIMM"), "$src1 = $dst",
 | 
			
		||||
           [(set QPR:$dst, (Ty (add QPR:$src1,
 | 
			
		||||
                                (Ty (ShOp QPR:$src2, (i32 imm:$SIMM))))))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -538,12 +551,14 @@ class N2VDShIns<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		|||
                bit op4, string OpcodeStr, ValueType Ty, SDNode ShOp>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, 0, op4,
 | 
			
		||||
           (outs DPR:$dst), (ins DPR:$src1, DPR:$src2, i32imm:$SIMM),
 | 
			
		||||
           NoItinerary, 
 | 
			
		||||
           !strconcat(OpcodeStr, "\t$dst, $src2, $SIMM"), "$src1 = $dst",
 | 
			
		||||
           [(set DPR:$dst, (Ty (ShOp DPR:$src1, DPR:$src2, (i32 imm:$SIMM))))]>;
 | 
			
		||||
class N2VQShIns<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		||||
                bit op4, string OpcodeStr, ValueType Ty, SDNode ShOp>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, 1, op4,
 | 
			
		||||
           (outs QPR:$dst), (ins QPR:$src1, QPR:$src2, i32imm:$SIMM),
 | 
			
		||||
           NoItinerary, 
 | 
			
		||||
           !strconcat(OpcodeStr, "\t$dst, $src2, $SIMM"), "$src1 = $dst",
 | 
			
		||||
           [(set QPR:$dst, (Ty (ShOp QPR:$src1, QPR:$src2, (i32 imm:$SIMM))))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -553,14 +568,14 @@ class N2VCvtD<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		|||
              bit op4, string OpcodeStr, ValueType ResTy, ValueType OpTy,
 | 
			
		||||
              Intrinsic IntOp>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, 0, op4,
 | 
			
		||||
           (outs DPR:$dst), (ins DPR:$src, i32imm:$SIMM),
 | 
			
		||||
           (outs DPR:$dst), (ins DPR:$src, i32imm:$SIMM), NoItinerary, 
 | 
			
		||||
           !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "",
 | 
			
		||||
           [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src), (i32 imm:$SIMM))))]>;
 | 
			
		||||
class N2VCvtQ<bit op24, bit op23, bits<6> op21_16, bits<4> op11_8, bit op7,
 | 
			
		||||
              bit op4, string OpcodeStr, ValueType ResTy, ValueType OpTy,
 | 
			
		||||
              Intrinsic IntOp>
 | 
			
		||||
  : N2VImm<op24, op23, op21_16, op11_8, op7, 1, op4,
 | 
			
		||||
           (outs QPR:$dst), (ins QPR:$src, i32imm:$SIMM),
 | 
			
		||||
           (outs QPR:$dst), (ins QPR:$src, i32imm:$SIMM), NoItinerary, 
 | 
			
		||||
           !strconcat(OpcodeStr, "\t$dst, $src, $SIMM"), "",
 | 
			
		||||
           [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src), (i32 imm:$SIMM))))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1077,39 +1092,45 @@ def  VORRq    : N3VQ<0, 0, 0b10, 0b0001, 1, "vorr", v4i32, v4i32, or, 1>;
 | 
			
		|||
 | 
			
		||||
//   VBIC     : Vector Bitwise Bit Clear (AND NOT)
 | 
			
		||||
def  VBICd    : N3V<0, 0, 0b01, 0b0001, 0, 1, (outs DPR:$dst),
 | 
			
		||||
                    (ins DPR:$src1, DPR:$src2), "vbic\t$dst, $src1, $src2", "",
 | 
			
		||||
                    (ins DPR:$src1, DPR:$src2), NoItinerary,
 | 
			
		||||
                    "vbic\t$dst, $src1, $src2", "",
 | 
			
		||||
                    [(set DPR:$dst, (v2i32 (and DPR:$src1,(vnot DPR:$src2))))]>;
 | 
			
		||||
def  VBICq    : N3V<0, 0, 0b01, 0b0001, 1, 1, (outs QPR:$dst),
 | 
			
		||||
                    (ins QPR:$src1, QPR:$src2), "vbic\t$dst, $src1, $src2", "",
 | 
			
		||||
                    (ins QPR:$src1, QPR:$src2), NoItinerary,
 | 
			
		||||
                    "vbic\t$dst, $src1, $src2", "",
 | 
			
		||||
                    [(set QPR:$dst, (v4i32 (and QPR:$src1,(vnot QPR:$src2))))]>;
 | 
			
		||||
 | 
			
		||||
//   VORN     : Vector Bitwise OR NOT
 | 
			
		||||
def  VORNd    : N3V<0, 0, 0b11, 0b0001, 0, 1, (outs DPR:$dst),
 | 
			
		||||
                    (ins DPR:$src1, DPR:$src2), "vorn\t$dst, $src1, $src2", "",
 | 
			
		||||
                    (ins DPR:$src1, DPR:$src2), NoItinerary,
 | 
			
		||||
                    "vorn\t$dst, $src1, $src2", "",
 | 
			
		||||
                    [(set DPR:$dst, (v2i32 (or DPR:$src1, (vnot DPR:$src2))))]>;
 | 
			
		||||
def  VORNq    : N3V<0, 0, 0b11, 0b0001, 1, 1, (outs QPR:$dst),
 | 
			
		||||
                    (ins QPR:$src1, QPR:$src2), "vorn\t$dst, $src1, $src2", "",
 | 
			
		||||
                    (ins QPR:$src1, QPR:$src2), NoItinerary,
 | 
			
		||||
                    "vorn\t$dst, $src1, $src2", "",
 | 
			
		||||
                    [(set QPR:$dst, (v4i32 (or QPR:$src1, (vnot QPR:$src2))))]>;
 | 
			
		||||
 | 
			
		||||
//   VMVN     : Vector Bitwise NOT
 | 
			
		||||
def  VMVNd    : N2V<0b11, 0b11, 0b00, 0b00, 0b01011, 0, 0,
 | 
			
		||||
                    (outs DPR:$dst), (ins DPR:$src), "vmvn\t$dst, $src", "",
 | 
			
		||||
                    (outs DPR:$dst), (ins DPR:$src), NoItinerary,
 | 
			
		||||
                    "vmvn\t$dst, $src", "",
 | 
			
		||||
                    [(set DPR:$dst, (v2i32 (vnot DPR:$src)))]>;
 | 
			
		||||
def  VMVNq    : N2V<0b11, 0b11, 0b00, 0b00, 0b01011, 1, 0,
 | 
			
		||||
                    (outs QPR:$dst), (ins QPR:$src), "vmvn\t$dst, $src", "",
 | 
			
		||||
                    (outs QPR:$dst), (ins QPR:$src), NoItinerary,
 | 
			
		||||
                    "vmvn\t$dst, $src", "",
 | 
			
		||||
                    [(set QPR:$dst, (v4i32 (vnot QPR:$src)))]>;
 | 
			
		||||
def : Pat<(v2i32 (vnot_conv DPR:$src)), (VMVNd DPR:$src)>;
 | 
			
		||||
def : Pat<(v4i32 (vnot_conv QPR:$src)), (VMVNq QPR:$src)>;
 | 
			
		||||
 | 
			
		||||
//   VBSL     : Vector Bitwise Select
 | 
			
		||||
def  VBSLd    : N3V<1, 0, 0b01, 0b0001, 0, 1, (outs DPR:$dst),
 | 
			
		||||
                    (ins DPR:$src1, DPR:$src2, DPR:$src3),
 | 
			
		||||
                    (ins DPR:$src1, DPR:$src2, DPR:$src3), NoItinerary,
 | 
			
		||||
                    "vbsl\t$dst, $src2, $src3", "$src1 = $dst",
 | 
			
		||||
                    [(set DPR:$dst,
 | 
			
		||||
                      (v2i32 (or (and DPR:$src2, DPR:$src1),
 | 
			
		||||
                                 (and DPR:$src3, (vnot DPR:$src1)))))]>;
 | 
			
		||||
def  VBSLq    : N3V<1, 0, 0b01, 0b0001, 1, 1, (outs QPR:$dst),
 | 
			
		||||
                    (ins QPR:$src1, QPR:$src2, QPR:$src3),
 | 
			
		||||
                    (ins QPR:$src1, QPR:$src2, QPR:$src3), NoItinerary,
 | 
			
		||||
                    "vbsl\t$dst, $src2, $src3", "$src1 = $dst",
 | 
			
		||||
                    [(set QPR:$dst,
 | 
			
		||||
                      (v4i32 (or (and QPR:$src2, QPR:$src1),
 | 
			
		||||
| 
						 | 
				
			
			@ -1402,10 +1423,12 @@ def vneg_conv : PatFrag<(ops node:$in), (sub immAllZerosV_bc, node:$in)>;
 | 
			
		|||
 | 
			
		||||
class VNEGD<bits<2> size, string OpcodeStr, ValueType Ty>
 | 
			
		||||
  : N2V<0b11, 0b11, size, 0b01, 0b00111, 0, 0, (outs DPR:$dst), (ins DPR:$src),
 | 
			
		||||
        NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set DPR:$dst, (Ty (vneg DPR:$src)))]>;
 | 
			
		||||
class VNEGQ<bits<2> size, string OpcodeStr, ValueType Ty>
 | 
			
		||||
  : N2V<0b11, 0b11, size, 0b01, 0b00111, 1, 0, (outs QPR:$dst), (ins QPR:$src),
 | 
			
		||||
        NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set QPR:$dst, (Ty (vneg QPR:$src)))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1419,10 +1442,12 @@ def  VNEGs32q : VNEGQ<0b10, "vneg.s32", v4i32>;
 | 
			
		|||
 | 
			
		||||
//   VNEG     : Vector Negate (floating-point)
 | 
			
		||||
def  VNEGf32d : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 0, 0,
 | 
			
		||||
                    (outs DPR:$dst), (ins DPR:$src), "vneg.f32\t$dst, $src", "",
 | 
			
		||||
                    (outs DPR:$dst), (ins DPR:$src), NoItinerary,
 | 
			
		||||
                    "vneg.f32\t$dst, $src", "",
 | 
			
		||||
                    [(set DPR:$dst, (v2f32 (fneg DPR:$src)))]>;
 | 
			
		||||
def  VNEGf32q : N2V<0b11, 0b11, 0b10, 0b01, 0b01111, 1, 0,
 | 
			
		||||
                    (outs QPR:$dst), (ins QPR:$src), "vneg.f32\t$dst, $src", "",
 | 
			
		||||
                    (outs QPR:$dst), (ins QPR:$src), NoItinerary,
 | 
			
		||||
                    "vneg.f32\t$dst, $src", "",
 | 
			
		||||
                    [(set QPR:$dst, (v4f32 (fneg QPR:$src)))]>;
 | 
			
		||||
def : N2VDInts<fneg, VNEGf32d>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1456,9 +1481,9 @@ def  VCNTq    : N2VQInt<0b11, 0b11, 0b00, 0b00, 0b01010, 0, "vcnt.8",
 | 
			
		|||
//   VMOV     : Vector Move (Register)
 | 
			
		||||
 | 
			
		||||
def  VMOVD    : N3V<0, 0, 0b10, 0b0001, 0, 1, (outs DPR:$dst), (ins DPR:$src),
 | 
			
		||||
                    "vmov\t$dst, $src", "", []>;
 | 
			
		||||
                    NoItinerary, "vmov\t$dst, $src", "", []>;
 | 
			
		||||
def  VMOVQ    : N3V<0, 0, 0b10, 0b0001, 1, 1, (outs QPR:$dst), (ins QPR:$src),
 | 
			
		||||
                    "vmov\t$dst, $src", "", []>;
 | 
			
		||||
                    NoItinerary, "vmov\t$dst, $src", "", []>;
 | 
			
		||||
 | 
			
		||||
//   VMOV     : Vector Move (Immediate)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1498,58 +1523,66 @@ def vmovImm64 : PatLeaf<(build_vector), [{
 | 
			
		|||
// be encoded based on the immed values.
 | 
			
		||||
 | 
			
		||||
def VMOVv8i8  : N1ModImm<1, 0b000, 0b1110, 0, 0, 0, 1, (outs DPR:$dst),
 | 
			
		||||
                         (ins i8imm:$SIMM), "vmov.i8\t$dst, $SIMM", "",
 | 
			
		||||
                         (ins i8imm:$SIMM), NoItinerary,
 | 
			
		||||
                         "vmov.i8\t$dst, $SIMM", "",
 | 
			
		||||
                         [(set DPR:$dst, (v8i8 vmovImm8:$SIMM))]>;
 | 
			
		||||
def VMOVv16i8 : N1ModImm<1, 0b000, 0b1110, 0, 1, 0, 1, (outs QPR:$dst),
 | 
			
		||||
                         (ins i8imm:$SIMM), "vmov.i8\t$dst, $SIMM", "",
 | 
			
		||||
                         (ins i8imm:$SIMM), NoItinerary,
 | 
			
		||||
                         "vmov.i8\t$dst, $SIMM", "",
 | 
			
		||||
                         [(set QPR:$dst, (v16i8 vmovImm8:$SIMM))]>;
 | 
			
		||||
 | 
			
		||||
def VMOVv4i16 : N1ModImm<1, 0b000, 0b1000, 0, 0, 0, 1, (outs DPR:$dst),
 | 
			
		||||
                         (ins i16imm:$SIMM), "vmov.i16\t$dst, $SIMM", "",
 | 
			
		||||
                         (ins i16imm:$SIMM), NoItinerary,
 | 
			
		||||
                         "vmov.i16\t$dst, $SIMM", "",
 | 
			
		||||
                         [(set DPR:$dst, (v4i16 vmovImm16:$SIMM))]>;
 | 
			
		||||
def VMOVv8i16 : N1ModImm<1, 0b000, 0b1000, 0, 1, 0, 1, (outs QPR:$dst),
 | 
			
		||||
                         (ins i16imm:$SIMM), "vmov.i16\t$dst, $SIMM", "",
 | 
			
		||||
                         (ins i16imm:$SIMM), NoItinerary,
 | 
			
		||||
                         "vmov.i16\t$dst, $SIMM", "",
 | 
			
		||||
                         [(set QPR:$dst, (v8i16 vmovImm16:$SIMM))]>;
 | 
			
		||||
 | 
			
		||||
def VMOVv2i32 : N1ModImm<1, 0b000, 0b0000, 0, 0, 0, 1, (outs DPR:$dst),
 | 
			
		||||
                         (ins i32imm:$SIMM), "vmov.i32\t$dst, $SIMM", "",
 | 
			
		||||
                         (ins i32imm:$SIMM), NoItinerary,
 | 
			
		||||
                         "vmov.i32\t$dst, $SIMM", "",
 | 
			
		||||
                         [(set DPR:$dst, (v2i32 vmovImm32:$SIMM))]>;
 | 
			
		||||
def VMOVv4i32 : N1ModImm<1, 0b000, 0b0000, 0, 1, 0, 1, (outs QPR:$dst),
 | 
			
		||||
                         (ins i32imm:$SIMM), "vmov.i32\t$dst, $SIMM", "",
 | 
			
		||||
                         (ins i32imm:$SIMM), NoItinerary,
 | 
			
		||||
                         "vmov.i32\t$dst, $SIMM", "",
 | 
			
		||||
                         [(set QPR:$dst, (v4i32 vmovImm32:$SIMM))]>;
 | 
			
		||||
 | 
			
		||||
def VMOVv1i64 : N1ModImm<1, 0b000, 0b1110, 0, 0, 1, 1, (outs DPR:$dst),
 | 
			
		||||
                         (ins i64imm:$SIMM), "vmov.i64\t$dst, $SIMM", "",
 | 
			
		||||
                         (ins i64imm:$SIMM), NoItinerary,
 | 
			
		||||
                         "vmov.i64\t$dst, $SIMM", "",
 | 
			
		||||
                         [(set DPR:$dst, (v1i64 vmovImm64:$SIMM))]>;
 | 
			
		||||
def VMOVv2i64 : N1ModImm<1, 0b000, 0b1110, 0, 1, 1, 1, (outs QPR:$dst),
 | 
			
		||||
                         (ins i64imm:$SIMM), "vmov.i64\t$dst, $SIMM", "",
 | 
			
		||||
                         (ins i64imm:$SIMM), NoItinerary,
 | 
			
		||||
                         "vmov.i64\t$dst, $SIMM", "",
 | 
			
		||||
                         [(set QPR:$dst, (v2i64 vmovImm64:$SIMM))]>;
 | 
			
		||||
 | 
			
		||||
//   VMOV     : Vector Get Lane (move scalar to ARM core register)
 | 
			
		||||
 | 
			
		||||
def VGETLNs8  : NVGetLane<0b11100101, 0b1011, 0b00,
 | 
			
		||||
                          (outs GPR:$dst), (ins DPR:$src, i32imm:$lane),
 | 
			
		||||
                          "vmov", ".s8\t$dst, $src[$lane]",
 | 
			
		||||
                          NoItinerary, "vmov", ".s8\t$dst, $src[$lane]",
 | 
			
		||||
                          [(set GPR:$dst, (NEONvgetlanes (v8i8 DPR:$src),
 | 
			
		||||
                                           imm:$lane))]>;
 | 
			
		||||
def VGETLNs16 : NVGetLane<0b11100001, 0b1011, 0b01,
 | 
			
		||||
                          (outs GPR:$dst), (ins DPR:$src, i32imm:$lane),
 | 
			
		||||
                          "vmov", ".s16\t$dst, $src[$lane]",
 | 
			
		||||
                          NoItinerary, "vmov", ".s16\t$dst, $src[$lane]",
 | 
			
		||||
                          [(set GPR:$dst, (NEONvgetlanes (v4i16 DPR:$src),
 | 
			
		||||
                                           imm:$lane))]>;
 | 
			
		||||
def VGETLNu8  : NVGetLane<0b11101101, 0b1011, 0b00,
 | 
			
		||||
                          (outs GPR:$dst), (ins DPR:$src, i32imm:$lane),
 | 
			
		||||
                          "vmov", ".u8\t$dst, $src[$lane]",
 | 
			
		||||
                          NoItinerary, "vmov", ".u8\t$dst, $src[$lane]",
 | 
			
		||||
                          [(set GPR:$dst, (NEONvgetlaneu (v8i8 DPR:$src),
 | 
			
		||||
                                           imm:$lane))]>;
 | 
			
		||||
def VGETLNu16 : NVGetLane<0b11101001, 0b1011, 0b01,
 | 
			
		||||
                          (outs GPR:$dst), (ins DPR:$src, i32imm:$lane),
 | 
			
		||||
                          "vmov", ".u16\t$dst, $src[$lane]",
 | 
			
		||||
                          NoItinerary, "vmov", ".u16\t$dst, $src[$lane]",
 | 
			
		||||
                          [(set GPR:$dst, (NEONvgetlaneu (v4i16 DPR:$src),
 | 
			
		||||
                                           imm:$lane))]>;
 | 
			
		||||
def VGETLNi32 : NVGetLane<0b11100001, 0b1011, 0b00,
 | 
			
		||||
                          (outs GPR:$dst), (ins DPR:$src, i32imm:$lane),
 | 
			
		||||
                          "vmov", ".32\t$dst, $src[$lane]",
 | 
			
		||||
                          NoItinerary, "vmov", ".32\t$dst, $src[$lane]",
 | 
			
		||||
                          [(set GPR:$dst, (extractelt (v2i32 DPR:$src),
 | 
			
		||||
                                           imm:$lane))]>;
 | 
			
		||||
// def VGETLNf32: see FMRDH and FMRDL in ARMInstrVFP.td
 | 
			
		||||
| 
						 | 
				
			
			@ -1584,17 +1617,17 @@ def : Pat<(extractelt (v2f64 QPR:$src1), imm:$src2),
 | 
			
		|||
let Constraints = "$src1 = $dst" in {
 | 
			
		||||
def VSETLNi8  : NVSetLane<0b11100100, 0b1011, 0b00, (outs DPR:$dst),
 | 
			
		||||
                          (ins DPR:$src1, GPR:$src2, i32imm:$lane),
 | 
			
		||||
                          "vmov", ".8\t$dst[$lane], $src2",
 | 
			
		||||
                          NoItinerary, "vmov", ".8\t$dst[$lane], $src2",
 | 
			
		||||
                          [(set DPR:$dst, (vector_insert (v8i8 DPR:$src1),
 | 
			
		||||
                                           GPR:$src2, imm:$lane))]>;
 | 
			
		||||
def VSETLNi16 : NVSetLane<0b11100000, 0b1011, 0b01, (outs DPR:$dst),
 | 
			
		||||
                          (ins DPR:$src1, GPR:$src2, i32imm:$lane),
 | 
			
		||||
                          "vmov", ".16\t$dst[$lane], $src2",
 | 
			
		||||
                          NoItinerary, "vmov", ".16\t$dst[$lane], $src2",
 | 
			
		||||
                          [(set DPR:$dst, (vector_insert (v4i16 DPR:$src1),
 | 
			
		||||
                                           GPR:$src2, imm:$lane))]>;
 | 
			
		||||
def VSETLNi32 : NVSetLane<0b11100000, 0b1011, 0b00, (outs DPR:$dst),
 | 
			
		||||
                          (ins DPR:$src1, GPR:$src2, i32imm:$lane),
 | 
			
		||||
                          "vmov", ".32\t$dst[$lane], $src2",
 | 
			
		||||
                          NoItinerary, "vmov", ".32\t$dst[$lane], $src2",
 | 
			
		||||
                          [(set DPR:$dst, (insertelt (v2i32 DPR:$src1),
 | 
			
		||||
                                           GPR:$src2, imm:$lane))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1632,11 +1665,11 @@ def splat_lo : PatFrag<(ops node:$lhs, node:$rhs),
 | 
			
		|||
 | 
			
		||||
class VDUPD<bits<8> opcod1, bits<2> opcod3, string asmSize, ValueType Ty>
 | 
			
		||||
  : NVDup<opcod1, 0b1011, opcod3, (outs DPR:$dst), (ins GPR:$src),
 | 
			
		||||
          "vdup", !strconcat(asmSize, "\t$dst, $src"),
 | 
			
		||||
          NoItinerary, "vdup", !strconcat(asmSize, "\t$dst, $src"),
 | 
			
		||||
          [(set DPR:$dst, (Ty (splat_lo (scalar_to_vector GPR:$src), undef)))]>;
 | 
			
		||||
class VDUPQ<bits<8> opcod1, bits<2> opcod3, string asmSize, ValueType Ty>
 | 
			
		||||
  : NVDup<opcod1, 0b1011, opcod3, (outs QPR:$dst), (ins GPR:$src),
 | 
			
		||||
          "vdup", !strconcat(asmSize, "\t$dst, $src"),
 | 
			
		||||
          NoItinerary, "vdup", !strconcat(asmSize, "\t$dst, $src"),
 | 
			
		||||
          [(set QPR:$dst, (Ty (splat_lo (scalar_to_vector GPR:$src), undef)))]>;
 | 
			
		||||
 | 
			
		||||
def  VDUP8d   : VDUPD<0b11101100, 0b00, ".8", v8i8>;
 | 
			
		||||
| 
						 | 
				
			
			@ -1647,13 +1680,13 @@ def  VDUP16q  : VDUPQ<0b11101010, 0b01, ".16", v8i16>;
 | 
			
		|||
def  VDUP32q  : VDUPQ<0b11101010, 0b00, ".32", v4i32>;
 | 
			
		||||
 | 
			
		||||
def  VDUPfd   : NVDup<0b11101000, 0b1011, 0b00, (outs DPR:$dst), (ins GPR:$src),
 | 
			
		||||
                      "vdup", ".32\t$dst, $src",
 | 
			
		||||
                      NoItinerary, "vdup", ".32\t$dst, $src",
 | 
			
		||||
                      [(set DPR:$dst, (v2f32 (splat_lo
 | 
			
		||||
                                              (scalar_to_vector
 | 
			
		||||
                                               (f32 (bitconvert GPR:$src))),
 | 
			
		||||
                                              undef)))]>;
 | 
			
		||||
def  VDUPfq   : NVDup<0b11101010, 0b1011, 0b00, (outs QPR:$dst), (ins GPR:$src),
 | 
			
		||||
                      "vdup", ".32\t$dst, $src",
 | 
			
		||||
                      NoItinerary, "vdup", ".32\t$dst, $src",
 | 
			
		||||
                      [(set QPR:$dst, (v4f32 (splat_lo
 | 
			
		||||
                                              (scalar_to_vector
 | 
			
		||||
                                               (f32 (bitconvert GPR:$src))),
 | 
			
		||||
| 
						 | 
				
			
			@ -1674,7 +1707,7 @@ def splat_lane : PatFrag<(ops node:$lhs, node:$rhs),
 | 
			
		|||
 | 
			
		||||
class VDUPLND<bits<2> op19_18, bits<2> op17_16, string OpcodeStr, ValueType Ty>
 | 
			
		||||
  : N2V<0b11, 0b11, op19_18, op17_16, 0b11000, 0, 0,
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src, i32imm:$lane),
 | 
			
		||||
        (outs DPR:$dst), (ins DPR:$src, i32imm:$lane), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src[$lane]"), "",
 | 
			
		||||
        [(set DPR:$dst, (Ty (splat_lane:$lane DPR:$src, undef)))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1683,7 +1716,7 @@ class VDUPLND<bits<2> op19_18, bits<2> op17_16, string OpcodeStr, ValueType Ty>
 | 
			
		|||
class VDUPLNQ<bits<2> op19_18, bits<2> op17_16, string OpcodeStr,
 | 
			
		||||
              ValueType ResTy, ValueType OpTy>
 | 
			
		||||
  : N2V<0b11, 0b11, op19_18, op17_16, 0b11000, 1, 0,
 | 
			
		||||
        (outs QPR:$dst), (ins DPR:$src, i32imm:$lane),
 | 
			
		||||
        (outs QPR:$dst), (ins DPR:$src, i32imm:$lane), NoItinerary,
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src[$lane]"), "",
 | 
			
		||||
        [(set QPR:$dst, (ResTy (NEONvduplaneq (OpTy DPR:$src), imm:$lane)))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1776,11 +1809,13 @@ def vrev16_shuffle : PatFrag<(ops node:$in),
 | 
			
		|||
 | 
			
		||||
class VREV64D<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
			
		||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 0, 0, (outs DPR:$dst),
 | 
			
		||||
        (ins DPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins DPR:$src), NoItinerary, 
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set DPR:$dst, (Ty (vrev64_shuffle (Ty DPR:$src))))]>;
 | 
			
		||||
class VREV64Q<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
			
		||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00000, 1, 0, (outs QPR:$dst),
 | 
			
		||||
        (ins QPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins QPR:$src), NoItinerary, 
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set QPR:$dst, (Ty (vrev64_shuffle (Ty QPR:$src))))]>;
 | 
			
		||||
 | 
			
		||||
def VREV64d8  : VREV64D<0b00, "vrev64.8", v8i8>;
 | 
			
		||||
| 
						 | 
				
			
			@ -1797,11 +1832,13 @@ def VREV64qf  : VREV64Q<0b10, "vrev64.32", v4f32>;
 | 
			
		|||
 | 
			
		||||
class VREV32D<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
			
		||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 0, 0, (outs DPR:$dst),
 | 
			
		||||
        (ins DPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins DPR:$src), NoItinerary, 
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set DPR:$dst, (Ty (vrev32_shuffle (Ty DPR:$src))))]>;
 | 
			
		||||
class VREV32Q<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
			
		||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00001, 1, 0, (outs QPR:$dst),
 | 
			
		||||
        (ins QPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins QPR:$src), NoItinerary, 
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set QPR:$dst, (Ty (vrev32_shuffle (Ty QPR:$src))))]>;
 | 
			
		||||
 | 
			
		||||
def VREV32d8  : VREV32D<0b00, "vrev32.8", v8i8>;
 | 
			
		||||
| 
						 | 
				
			
			@ -1814,11 +1851,13 @@ def VREV32q16 : VREV32Q<0b01, "vrev32.16", v8i16>;
 | 
			
		|||
 | 
			
		||||
class VREV16D<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
			
		||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 0, 0, (outs DPR:$dst),
 | 
			
		||||
        (ins DPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins DPR:$src), NoItinerary, 
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set DPR:$dst, (Ty (vrev16_shuffle (Ty DPR:$src))))]>;
 | 
			
		||||
class VREV16Q<bits<2> op19_18, string OpcodeStr, ValueType Ty>
 | 
			
		||||
  : N2V<0b11, 0b11, op19_18, 0b00, 0b00010, 1, 0, (outs QPR:$dst),
 | 
			
		||||
        (ins QPR:$src), !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        (ins QPR:$src), NoItinerary, 
 | 
			
		||||
        !strconcat(OpcodeStr, "\t$dst, $src"), "",
 | 
			
		||||
        [(set QPR:$dst, (Ty (vrev16_shuffle (Ty QPR:$src))))]>;
 | 
			
		||||
 | 
			
		||||
def VREV16d8  : VREV16D<0b00, "vrev16.8", v8i8>;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -117,34 +117,34 @@ def t_addrmode_sp : Operand<i32>,
 | 
			
		|||
 | 
			
		||||
let Defs = [SP], Uses = [SP] in {
 | 
			
		||||
def tADJCALLSTACKUP :
 | 
			
		||||
PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2),
 | 
			
		||||
PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary,
 | 
			
		||||
           "@ tADJCALLSTACKUP $amt1",
 | 
			
		||||
           [(ARMcallseq_end imm:$amt1, imm:$amt2)]>, Requires<[IsThumb1Only]>;
 | 
			
		||||
 | 
			
		||||
def tADJCALLSTACKDOWN :
 | 
			
		||||
PseudoInst<(outs), (ins i32imm:$amt),
 | 
			
		||||
PseudoInst<(outs), (ins i32imm:$amt), NoItinerary,
 | 
			
		||||
           "@ tADJCALLSTACKDOWN $amt",
 | 
			
		||||
           [(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// For both thumb1 and thumb2.
 | 
			
		||||
let isNotDuplicable = 1 in
 | 
			
		||||
def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp),
 | 
			
		||||
def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALU,
 | 
			
		||||
                 "$cp:\n\tadd $dst, pc",
 | 
			
		||||
                 [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>;
 | 
			
		||||
 | 
			
		||||
// PC relative add.
 | 
			
		||||
def tADDrPCi : T1I<(outs tGPR:$dst), (ins i32imm:$rhs),
 | 
			
		||||
def tADDrPCi : T1I<(outs tGPR:$dst), (ins i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                  "add $dst, pc, $rhs * 4", []>;
 | 
			
		||||
 | 
			
		||||
// ADD rd, sp, #imm8
 | 
			
		||||
// FIXME: hard code sp?
 | 
			
		||||
def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs),
 | 
			
		||||
def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                  "add $dst, $sp, $rhs * 4 @ addrspi", []>;
 | 
			
		||||
 | 
			
		||||
// ADD sp, sp, #imm7
 | 
			
		||||
// FIXME: hard code sp?
 | 
			
		||||
def tADDspi : T1It<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tADDspi : T1It<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                  "add $dst, $rhs * 4", []>;
 | 
			
		||||
 | 
			
		||||
// FIXME: Make use of the following?
 | 
			
		||||
| 
						 | 
				
			
			@ -156,14 +156,14 @@ def tADDspi : T1It<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
let isReturn = 1, isTerminator = 1 in {
 | 
			
		||||
  def tBX_RET : TI<(outs), (ins), "bx lr", [(ARMretflag)]>;
 | 
			
		||||
  def tBX_RET : TI<(outs), (ins), IIC_Br, "bx lr", [(ARMretflag)]>;
 | 
			
		||||
  // Alternative return instruction used by vararg functions.
 | 
			
		||||
  def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), "bx $target", []>;
 | 
			
		||||
  def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx $target", []>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FIXME: remove when we have a way to marking a MI with these properties.
 | 
			
		||||
let isReturn = 1, isTerminator = 1 in
 | 
			
		||||
def tPOP_RET : T1I<(outs reglist:$dst1, variable_ops), (ins),
 | 
			
		||||
def tPOP_RET : T1I<(outs reglist:$dst1, variable_ops), (ins), IIC_Br, 
 | 
			
		||||
                   "pop $dst1", []>;
 | 
			
		||||
 | 
			
		||||
let isCall = 1,
 | 
			
		||||
| 
						 | 
				
			
			@ -172,25 +172,25 @@ let isCall = 1,
 | 
			
		|||
          D16, D17, D18, D19, D20, D21, D22, D23,
 | 
			
		||||
          D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in {
 | 
			
		||||
  // Also used for Thumb2
 | 
			
		||||
  def tBL  : TIx2<(outs), (ins i32imm:$func, variable_ops),
 | 
			
		||||
  def tBL  : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
 | 
			
		||||
                   "bl ${func:call}",
 | 
			
		||||
                   [(ARMtcall tglobaladdr:$func)]>,
 | 
			
		||||
             Requires<[IsThumb, IsNotDarwin]>;
 | 
			
		||||
 | 
			
		||||
  // ARMv5T and above, also used for Thumb2
 | 
			
		||||
  def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops),
 | 
			
		||||
  def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
 | 
			
		||||
                    "blx ${func:call}",
 | 
			
		||||
                    [(ARMcall tglobaladdr:$func)]>,
 | 
			
		||||
              Requires<[IsThumb, HasV5T, IsNotDarwin]>;
 | 
			
		||||
 | 
			
		||||
  // Also used for Thumb2
 | 
			
		||||
  def tBLXr : TI<(outs), (ins GPR:$func, variable_ops),
 | 
			
		||||
  def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 
 | 
			
		||||
                  "blx $func",
 | 
			
		||||
                  [(ARMtcall GPR:$func)]>,
 | 
			
		||||
              Requires<[IsThumb, HasV5T, IsNotDarwin]>;
 | 
			
		||||
 | 
			
		||||
  // ARMv4T
 | 
			
		||||
  def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops),
 | 
			
		||||
  def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 
 | 
			
		||||
                  "mov lr, pc\n\tbx $func",
 | 
			
		||||
                  [(ARMcall_nolink tGPR:$func)]>,
 | 
			
		||||
            Requires<[IsThumb1Only, IsNotDarwin]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -203,25 +203,25 @@ let isCall = 1,
 | 
			
		|||
          D16, D17, D18, D19, D20, D21, D22, D23,
 | 
			
		||||
          D24, D25, D26, D27, D28, D29, D30, D31, CPSR] in {
 | 
			
		||||
  // Also used for Thumb2
 | 
			
		||||
  def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops),
 | 
			
		||||
  def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
 | 
			
		||||
                   "bl ${func:call}",
 | 
			
		||||
                   [(ARMtcall tglobaladdr:$func)]>,
 | 
			
		||||
              Requires<[IsThumb, IsDarwin]>;
 | 
			
		||||
 | 
			
		||||
  // ARMv5T and above, also used for Thumb2
 | 
			
		||||
  def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops),
 | 
			
		||||
  def tBLXi_r9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br, 
 | 
			
		||||
                      "blx ${func:call}",
 | 
			
		||||
                      [(ARMcall tglobaladdr:$func)]>,
 | 
			
		||||
                 Requires<[IsThumb, HasV5T, IsDarwin]>;
 | 
			
		||||
 | 
			
		||||
  // Also used for Thumb2
 | 
			
		||||
  def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops),
 | 
			
		||||
  def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br, 
 | 
			
		||||
                  "blx $func",
 | 
			
		||||
                  [(ARMtcall GPR:$func)]>,
 | 
			
		||||
                 Requires<[IsThumb, HasV5T, IsDarwin]>;
 | 
			
		||||
 | 
			
		||||
  // ARMv4T
 | 
			
		||||
  def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops),
 | 
			
		||||
  def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br, 
 | 
			
		||||
                  "mov lr, pc\n\tbx $func",
 | 
			
		||||
                  [(ARMcall_nolink tGPR:$func)]>,
 | 
			
		||||
              Requires<[IsThumb1Only, IsDarwin]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -230,16 +230,16 @@ let isCall = 1,
 | 
			
		|||
let isBranch = 1, isTerminator = 1 in {
 | 
			
		||||
  let isBarrier = 1 in {
 | 
			
		||||
    let isPredicable = 1 in
 | 
			
		||||
    def tB   : T1I<(outs), (ins brtarget:$target), "b $target",
 | 
			
		||||
                   [(br bb:$target)]>;
 | 
			
		||||
    def tB   : T1I<(outs), (ins brtarget:$target), IIC_Br,
 | 
			
		||||
                   "b $target", [(br bb:$target)]>;
 | 
			
		||||
 | 
			
		||||
  // Far jump
 | 
			
		||||
  def tBfar : TIx2<(outs), (ins brtarget:$target), 
 | 
			
		||||
  def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br, 
 | 
			
		||||
                    "bl $target\t@ far jump",[]>;
 | 
			
		||||
 | 
			
		||||
  def tBR_JTr : T1JTI<(outs),
 | 
			
		||||
                      (ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
 | 
			
		||||
                      "mov pc, $target\n\t.align\t2\n$jt",
 | 
			
		||||
                      IIC_Br, "mov pc, $target\n\t.align\t2\n$jt",
 | 
			
		||||
                      [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -247,7 +247,8 @@ let isBranch = 1, isTerminator = 1 in {
 | 
			
		|||
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
 | 
			
		||||
// a two-value operand where a dag node expects two operands. :(
 | 
			
		||||
let isBranch = 1, isTerminator = 1 in
 | 
			
		||||
  def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), "b$cc $target",
 | 
			
		||||
  def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br,
 | 
			
		||||
                 "b$cc $target",
 | 
			
		||||
                 [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			@ -255,70 +256,70 @@ let isBranch = 1, isTerminator = 1 in
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
let canFoldAsLoad = 1 in
 | 
			
		||||
def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr),
 | 
			
		||||
def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoad, 
 | 
			
		||||
               "ldr", " $dst, $addr",
 | 
			
		||||
               [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>;
 | 
			
		||||
 | 
			
		||||
def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr),
 | 
			
		||||
def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoad,
 | 
			
		||||
                "ldrb", " $dst, $addr",
 | 
			
		||||
                [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>;
 | 
			
		||||
 | 
			
		||||
def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr),
 | 
			
		||||
def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoad,
 | 
			
		||||
                "ldrh", " $dst, $addr",
 | 
			
		||||
                [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>;
 | 
			
		||||
 | 
			
		||||
let AddedComplexity = 10 in
 | 
			
		||||
def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr),
 | 
			
		||||
def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoad,
 | 
			
		||||
                 "ldrsb", " $dst, $addr",
 | 
			
		||||
                 [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>;
 | 
			
		||||
 | 
			
		||||
let AddedComplexity = 10 in
 | 
			
		||||
def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr),
 | 
			
		||||
def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoad,
 | 
			
		||||
                 "ldrsh", " $dst, $addr",
 | 
			
		||||
                 [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>;
 | 
			
		||||
 | 
			
		||||
let canFoldAsLoad = 1 in
 | 
			
		||||
def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr),
 | 
			
		||||
def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoad,
 | 
			
		||||
                  "ldr", " $dst, $addr",
 | 
			
		||||
                  [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>;
 | 
			
		||||
 | 
			
		||||
// Special instruction for restore. It cannot clobber condition register
 | 
			
		||||
// when it's expanded by eliminateCallFramePseudoInstr().
 | 
			
		||||
let canFoldAsLoad = 1, mayLoad = 1 in
 | 
			
		||||
def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr),
 | 
			
		||||
def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoad,
 | 
			
		||||
                    "ldr", " $dst, $addr", []>;
 | 
			
		||||
 | 
			
		||||
// Load tconstpool
 | 
			
		||||
let canFoldAsLoad = 1 in
 | 
			
		||||
def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr),
 | 
			
		||||
def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoad,
 | 
			
		||||
                  "ldr", " $dst, $addr",
 | 
			
		||||
                  [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>;
 | 
			
		||||
 | 
			
		||||
// Special LDR for loads from non-pc-relative constpools.
 | 
			
		||||
let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1 in
 | 
			
		||||
def tLDRcp  : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr),
 | 
			
		||||
def tLDRcp  : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoad,
 | 
			
		||||
                  "ldr", " $dst, $addr", []>;
 | 
			
		||||
 | 
			
		||||
def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr),
 | 
			
		||||
def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStore,
 | 
			
		||||
               "str", " $src, $addr",
 | 
			
		||||
               [(store tGPR:$src, t_addrmode_s4:$addr)]>;
 | 
			
		||||
 | 
			
		||||
def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr),
 | 
			
		||||
def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStore,
 | 
			
		||||
                 "strb", " $src, $addr",
 | 
			
		||||
                 [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>;
 | 
			
		||||
 | 
			
		||||
def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr),
 | 
			
		||||
def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStore,
 | 
			
		||||
                 "strh", " $src, $addr",
 | 
			
		||||
                 [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>;
 | 
			
		||||
 | 
			
		||||
def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr),
 | 
			
		||||
def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStore,
 | 
			
		||||
                   "str", " $src, $addr",
 | 
			
		||||
                   [(store tGPR:$src, t_addrmode_sp:$addr)]>;
 | 
			
		||||
 | 
			
		||||
let mayStore = 1 in {
 | 
			
		||||
// Special instruction for spill. It cannot clobber condition register
 | 
			
		||||
// when it's expanded by eliminateCallFramePseudoInstr().
 | 
			
		||||
def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr),
 | 
			
		||||
def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStore,
 | 
			
		||||
                  "str", " $src, $addr", []>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -330,11 +331,11 @@ def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr),
 | 
			
		|||
// TODO: Allow these to be predicated
 | 
			
		||||
 | 
			
		||||
let mayLoad = 1 in
 | 
			
		||||
def tPOP : T1I<(outs reglist:$dst1, variable_ops), (ins),
 | 
			
		||||
def tPOP : T1I<(outs reglist:$dst1, variable_ops), (ins), IIC_Br,
 | 
			
		||||
               "pop $dst1", []>;
 | 
			
		||||
 | 
			
		||||
let mayStore = 1 in
 | 
			
		||||
def tPUSH : T1I<(outs), (ins reglist:$src1, variable_ops),
 | 
			
		||||
def tPUSH : T1I<(outs), (ins reglist:$src1, variable_ops), IIC_Br,
 | 
			
		||||
                "push $src1", []>;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			@ -343,66 +344,66 @@ def tPUSH : T1I<(outs), (ins reglist:$src1, variable_ops),
 | 
			
		|||
 | 
			
		||||
// Add with carry register
 | 
			
		||||
let isCommutable = 1, Uses = [CPSR] in
 | 
			
		||||
def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                 "adc", " $dst, $rhs",
 | 
			
		||||
                 [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// Add immediate
 | 
			
		||||
def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                   "add", " $dst, $lhs, $rhs",
 | 
			
		||||
                   [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                   "add", " $dst, $rhs",
 | 
			
		||||
                   [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// Add register
 | 
			
		||||
let isCommutable = 1 in
 | 
			
		||||
def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                   "add", " $dst, $lhs, $rhs",
 | 
			
		||||
                   [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
let neverHasSideEffects = 1 in
 | 
			
		||||
def tADDhirr : T1pIt<(outs tGPR:$dst), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
def tADDhirr : T1pIt<(outs tGPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                     "add", " $dst, $rhs @ addhirr", []>;
 | 
			
		||||
 | 
			
		||||
// And register
 | 
			
		||||
let isCommutable = 1 in
 | 
			
		||||
def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                 "and", " $dst, $rhs",
 | 
			
		||||
                 [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// ASR immediate
 | 
			
		||||
def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                  "asr", " $dst, $lhs, $rhs",
 | 
			
		||||
                  [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>;
 | 
			
		||||
 | 
			
		||||
// ASR register
 | 
			
		||||
def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                   "asr", " $dst, $rhs",
 | 
			
		||||
                   [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// BIC register
 | 
			
		||||
def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                 "bic", " $dst, $rhs",
 | 
			
		||||
                 [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>;
 | 
			
		||||
 | 
			
		||||
// CMN register
 | 
			
		||||
let Defs = [CPSR] in {
 | 
			
		||||
def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                "cmn", " $lhs, $rhs",
 | 
			
		||||
                [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
 | 
			
		||||
def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                 "cmn", " $lhs, $rhs",
 | 
			
		||||
                 [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// CMP immediate
 | 
			
		||||
let Defs = [CPSR] in {
 | 
			
		||||
def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                  "cmp", " $lhs, $rhs",
 | 
			
		||||
                  [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>;
 | 
			
		||||
def tCMPZi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tCMPZi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                  "cmp", " $lhs, $rhs",
 | 
			
		||||
                  [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -410,49 +411,49 @@ def tCMPZi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs),
 | 
			
		|||
 | 
			
		||||
// CMP register
 | 
			
		||||
let Defs = [CPSR] in {
 | 
			
		||||
def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                 "cmp", " $lhs, $rhs",
 | 
			
		||||
                 [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>;
 | 
			
		||||
def tCMPZr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tCMPZr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                  "cmp", " $lhs, $rhs",
 | 
			
		||||
                  [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>;
 | 
			
		||||
 | 
			
		||||
// TODO: Make use of the followings cmp hi regs
 | 
			
		||||
def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                   "cmp", " $lhs, $rhs", []>;
 | 
			
		||||
def tCMPZhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
def tCMPZhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                    "cmp", " $lhs, $rhs", []>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// XOR register
 | 
			
		||||
let isCommutable = 1 in
 | 
			
		||||
def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                 "eor", " $dst, $rhs",
 | 
			
		||||
                 [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// LSL immediate
 | 
			
		||||
def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                  "lsl", " $dst, $lhs, $rhs",
 | 
			
		||||
                  [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>;
 | 
			
		||||
 | 
			
		||||
// LSL register
 | 
			
		||||
def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                   "lsl", " $dst, $rhs",
 | 
			
		||||
                   [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// LSR immediate
 | 
			
		||||
def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                  "lsr", " $dst, $lhs, $rhs",
 | 
			
		||||
                  [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>;
 | 
			
		||||
 | 
			
		||||
// LSR register
 | 
			
		||||
def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                   "lsr", " $dst, $rhs",
 | 
			
		||||
                   [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// move register
 | 
			
		||||
def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src),
 | 
			
		||||
def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iALU,
 | 
			
		||||
                  "mov", " $dst, $src",
 | 
			
		||||
                  [(set tGPR:$dst, imm0_255:$src)]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -461,45 +462,45 @@ def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src),
 | 
			
		|||
 | 
			
		||||
let neverHasSideEffects = 1 in {
 | 
			
		||||
// FIXME: Make this predicable.
 | 
			
		||||
def tMOVr       : T1I<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tMOVr       : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                      "mov $dst, $src", []>;
 | 
			
		||||
let Defs = [CPSR] in
 | 
			
		||||
def tMOVSr      : T1I<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tMOVSr      : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                       "movs $dst, $src", []>;
 | 
			
		||||
 | 
			
		||||
// FIXME: Make these predicable.
 | 
			
		||||
def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src),
 | 
			
		||||
def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
                       "mov $dst, $src\t@ hir2lor", []>;
 | 
			
		||||
def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                       "mov $dst, $src\t@ lor2hir", []>;
 | 
			
		||||
def tMOVgpr2gpr  : T1I<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def tMOVgpr2gpr  : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
                       "mov $dst, $src\t@ hir2hir", []>;
 | 
			
		||||
} // neverHasSideEffects
 | 
			
		||||
 | 
			
		||||
// multiply register
 | 
			
		||||
let isCommutable = 1 in
 | 
			
		||||
def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                 "mul", " $dst, $rhs",
 | 
			
		||||
                 [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// move inverse register
 | 
			
		||||
def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                "mvn", " $dst, $src",
 | 
			
		||||
                [(set tGPR:$dst, (not tGPR:$src))]>;
 | 
			
		||||
 | 
			
		||||
// bitwise or register
 | 
			
		||||
let isCommutable = 1 in
 | 
			
		||||
def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),  IIC_iALU,
 | 
			
		||||
                 "orr", " $dst, $rhs",
 | 
			
		||||
                 [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// swaps
 | 
			
		||||
def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                "rev", " $dst, $src",
 | 
			
		||||
                [(set tGPR:$dst, (bswap tGPR:$src))]>,
 | 
			
		||||
                Requires<[IsThumb1Only, HasV6]>;
 | 
			
		||||
 | 
			
		||||
def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                  "rev16", " $dst, $src",
 | 
			
		||||
             [(set tGPR:$dst,
 | 
			
		||||
                   (or (and (srl tGPR:$src, (i32 8)), 0xFF),
 | 
			
		||||
| 
						 | 
				
			
			@ -508,7 +509,7 @@ def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		|||
                               (and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>,
 | 
			
		||||
                Requires<[IsThumb1Only, HasV6]>;
 | 
			
		||||
 | 
			
		||||
def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                  "revsh", " $dst, $src",
 | 
			
		||||
                  [(set tGPR:$dst,
 | 
			
		||||
                        (sext_inreg
 | 
			
		||||
| 
						 | 
				
			
			@ -517,66 +518,66 @@ def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		|||
                  Requires<[IsThumb1Only, HasV6]>;
 | 
			
		||||
 | 
			
		||||
// rotate right register
 | 
			
		||||
def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                 "ror", " $dst, $rhs",
 | 
			
		||||
                 [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// negate register
 | 
			
		||||
def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                "rsb", " $dst, $src, #0",
 | 
			
		||||
                [(set tGPR:$dst, (ineg tGPR:$src))]>;
 | 
			
		||||
 | 
			
		||||
// Subtract with carry register
 | 
			
		||||
let Uses = [CPSR] in
 | 
			
		||||
def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                 "sbc", " $dst, $rhs",
 | 
			
		||||
                 [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// Subtract immediate
 | 
			
		||||
def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                  "sub", " $dst, $lhs, $rhs",
 | 
			
		||||
                  [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                   "sub", " $dst, $rhs",
 | 
			
		||||
                   [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// subtract register
 | 
			
		||||
def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                  "sub", " $dst, $lhs, $rhs",
 | 
			
		||||
                  [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>;
 | 
			
		||||
 | 
			
		||||
// TODO: A7-96: STMIA - store multiple.
 | 
			
		||||
 | 
			
		||||
def tSUBspi : T1It<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
 | 
			
		||||
def tSUBspi : T1It<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                  "sub $dst, $rhs * 4", []>;
 | 
			
		||||
 | 
			
		||||
// sign-extend byte
 | 
			
		||||
def tSXTB  : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tSXTB  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                  "sxtb", " $dst, $src",
 | 
			
		||||
                  [(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>,
 | 
			
		||||
                  Requires<[IsThumb1Only, HasV6]>;
 | 
			
		||||
 | 
			
		||||
// sign-extend short
 | 
			
		||||
def tSXTH  : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tSXTH  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                  "sxth", " $dst, $src",
 | 
			
		||||
                  [(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>,
 | 
			
		||||
                  Requires<[IsThumb1Only, HasV6]>;
 | 
			
		||||
 | 
			
		||||
// test
 | 
			
		||||
let isCommutable = 1, Defs = [CPSR] in
 | 
			
		||||
def tTST  : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs),
 | 
			
		||||
def tTST  : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
 | 
			
		||||
                 "tst", " $lhs, $rhs",
 | 
			
		||||
                 [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>;
 | 
			
		||||
 | 
			
		||||
// zero-extend byte
 | 
			
		||||
def tUXTB  : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tUXTB  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                  "uxtb", " $dst, $src",
 | 
			
		||||
                  [(set tGPR:$dst, (and tGPR:$src, 0xFF))]>,
 | 
			
		||||
                  Requires<[IsThumb1Only, HasV6]>;
 | 
			
		||||
 | 
			
		||||
// zero-extend short
 | 
			
		||||
def tUXTH  : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		||||
def tUXTH  : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
 | 
			
		||||
                  "uxth", " $dst, $src",
 | 
			
		||||
                  [(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>,
 | 
			
		||||
                  Requires<[IsThumb1Only, HasV6]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -587,16 +588,16 @@ def tUXTH  : T1pI<(outs tGPR:$dst), (ins tGPR:$src),
 | 
			
		|||
// FIXME: Add actual movcc in IT blocks for Thumb2.
 | 
			
		||||
let usesCustomDAGSchedInserter = 1 in  // Expanded by the scheduler.
 | 
			
		||||
  def tMOVCCr :
 | 
			
		||||
  PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc),
 | 
			
		||||
  PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc), IIC_iALU,
 | 
			
		||||
              "@ tMOVCCr $cc",
 | 
			
		||||
              [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>;
 | 
			
		||||
 | 
			
		||||
// tLEApcrel - Load a pc-relative address into a register without offending the
 | 
			
		||||
// assembler.
 | 
			
		||||
def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label),
 | 
			
		||||
def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label), IIC_iALU,
 | 
			
		||||
                    "adr $dst, #$label", []>;
 | 
			
		||||
 | 
			
		||||
def tLEApcrelJT : T1I<(outs tGPR:$dst), (ins i32imm:$label, i32imm:$id),
 | 
			
		||||
def tLEApcrelJT : T1I<(outs tGPR:$dst), (ins i32imm:$label, i32imm:$id), IIC_iALU,
 | 
			
		||||
                      "adr $dst, #${label}_${id:no_hash}", []>;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			@ -606,7 +607,7 @@ def tLEApcrelJT : T1I<(outs tGPR:$dst), (ins i32imm:$label, i32imm:$id),
 | 
			
		|||
// __aeabi_read_tp preserves the registers r1-r3.
 | 
			
		||||
let isCall = 1,
 | 
			
		||||
  Defs = [R0, LR] in {
 | 
			
		||||
  def tTPsoft  : TIx2<(outs), (ins),
 | 
			
		||||
  def tTPsoft  : TIx2<(outs), (ins), IIC_Br,
 | 
			
		||||
               "bl __aeabi_read_tp",
 | 
			
		||||
               [(set R0, ARMthread_pointer)]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -154,18 +154,18 @@ def t2addrmode_so_reg : Operand<i32>,
 | 
			
		|||
/// changed to modify CPSR.
 | 
			
		||||
multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{
 | 
			
		||||
   // shifted imm
 | 
			
		||||
   def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src),
 | 
			
		||||
   def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iALU,
 | 
			
		||||
                opc, " $dst, $src",
 | 
			
		||||
                [(set GPR:$dst, (opnode t2_so_imm:$src))]> {
 | 
			
		||||
     let isAsCheapAsAMove = Cheap;
 | 
			
		||||
     let isReMaterializable = ReMat;
 | 
			
		||||
   }
 | 
			
		||||
   // register
 | 
			
		||||
   def r : T2I<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
   def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
               opc, ".w $dst, $src",
 | 
			
		||||
                [(set GPR:$dst, (opnode GPR:$src))]>;
 | 
			
		||||
   // shifted register
 | 
			
		||||
   def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src),
 | 
			
		||||
   def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iALU,
 | 
			
		||||
               opc, ".w $dst, $src",
 | 
			
		||||
               [(set GPR:$dst, (opnode t2_so_reg:$src))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -176,17 +176,17 @@ multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{
 | 
			
		|||
multiclass T2I_bin_irs<string opc, PatFrag opnode, 
 | 
			
		||||
                       bit Commutable = 0, string wide =""> {
 | 
			
		||||
   // shifted imm
 | 
			
		||||
   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
 | 
			
		||||
   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, " $dst, $lhs, $rhs",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
 | 
			
		||||
   // register
 | 
			
		||||
   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, !strconcat(wide, " $dst, $lhs, $rhs"),
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
 | 
			
		||||
     let isCommutable = Commutable;
 | 
			
		||||
   }
 | 
			
		||||
   // shifted register
 | 
			
		||||
   def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
 | 
			
		||||
   def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, !strconcat(wide, " $dst, $lhs, $rhs"),
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -201,11 +201,11 @@ multiclass T2I_bin_w_irs<string opc, PatFrag opnode, bit Commutable = 0> :
 | 
			
		|||
/// T2I_bin_irs counterpart.
 | 
			
		||||
multiclass T2I_rbin_is<string opc, PatFrag opnode> {
 | 
			
		||||
   // shifted imm
 | 
			
		||||
   def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs),
 | 
			
		||||
   def ri : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs), IIC_iALU,
 | 
			
		||||
                opc, ".w $dst, $rhs, $lhs",
 | 
			
		||||
                [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
 | 
			
		||||
   // shifted register
 | 
			
		||||
   def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs),
 | 
			
		||||
   def rs : T2I<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs), IIC_iALU,
 | 
			
		||||
                opc, " $dst, $rhs, $lhs",
 | 
			
		||||
                [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -215,17 +215,17 @@ multiclass T2I_rbin_is<string opc, PatFrag opnode> {
 | 
			
		|||
let Defs = [CPSR] in {
 | 
			
		||||
multiclass T2I_bin_s_irs<string opc, PatFrag opnode, bit Commutable = 0> {
 | 
			
		||||
   // shifted imm
 | 
			
		||||
   def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
 | 
			
		||||
   def ri : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
 | 
			
		||||
                !strconcat(opc, "s"), ".w $dst, $lhs, $rhs",
 | 
			
		||||
                [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
 | 
			
		||||
   // register
 | 
			
		||||
   def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
   def rr : T2I<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                !strconcat(opc, "s"), ".w $dst, $lhs, $rhs",
 | 
			
		||||
                [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
 | 
			
		||||
     let isCommutable = Commutable;
 | 
			
		||||
   }
 | 
			
		||||
   // shifted register
 | 
			
		||||
   def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
 | 
			
		||||
   def rs : T2I<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
 | 
			
		||||
                !strconcat(opc, "s"), ".w $dst, $lhs, $rhs",
 | 
			
		||||
                [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -235,21 +235,21 @@ multiclass T2I_bin_s_irs<string opc, PatFrag opnode, bit Commutable = 0> {
 | 
			
		|||
/// patterns for a binary operation that produces a value.
 | 
			
		||||
multiclass T2I_bin_ii12rs<string opc, PatFrag opnode, bit Commutable = 0> {
 | 
			
		||||
   // shifted imm
 | 
			
		||||
   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
 | 
			
		||||
   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, ".w $dst, $lhs, $rhs",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
 | 
			
		||||
   // 12-bit imm
 | 
			
		||||
   def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
 | 
			
		||||
   def ri12 : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                   !strconcat(opc, "w"), " $dst, $lhs, $rhs",
 | 
			
		||||
                   [(set GPR:$dst, (opnode GPR:$lhs, imm0_4095:$rhs))]>;
 | 
			
		||||
   // register
 | 
			
		||||
   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, ".w $dst, $lhs, $rhs",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
 | 
			
		||||
     let isCommutable = Commutable;
 | 
			
		||||
   }
 | 
			
		||||
   // shifted register
 | 
			
		||||
   def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
 | 
			
		||||
   def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, ".w $dst, $lhs, $rhs",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -260,32 +260,32 @@ multiclass T2I_bin_ii12rs<string opc, PatFrag opnode, bit Commutable = 0> {
 | 
			
		|||
let Uses = [CPSR] in {
 | 
			
		||||
multiclass T2I_adde_sube_irs<string opc, PatFrag opnode, bit Commutable = 0> {
 | 
			
		||||
   // shifted imm
 | 
			
		||||
   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
 | 
			
		||||
   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, " $dst, $lhs, $rhs",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
 | 
			
		||||
                 Requires<[IsThumb2, CarryDefIsUnused]>;
 | 
			
		||||
   // register
 | 
			
		||||
   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, ".w $dst, $lhs, $rhs",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
 | 
			
		||||
                 Requires<[IsThumb2, CarryDefIsUnused]> {
 | 
			
		||||
     let isCommutable = Commutable;
 | 
			
		||||
   }
 | 
			
		||||
   // shifted register
 | 
			
		||||
   def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
 | 
			
		||||
   def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, ".w $dst, $lhs, $rhs",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
 | 
			
		||||
                 Requires<[IsThumb2, CarryDefIsUnused]>;
 | 
			
		||||
   // Carry setting variants
 | 
			
		||||
   // shifted imm
 | 
			
		||||
   def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
 | 
			
		||||
   def Sri : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
 | 
			
		||||
                  !strconcat(opc, "s $dst, $lhs, $rhs"),
 | 
			
		||||
                  [(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>,
 | 
			
		||||
                  Requires<[IsThumb2, CarryDefIsUsed]> {
 | 
			
		||||
                    let Defs = [CPSR];
 | 
			
		||||
                  }
 | 
			
		||||
   // register
 | 
			
		||||
   def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
   def Srr : T2XI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                  !strconcat(opc, "s.w $dst, $lhs, $rhs"),
 | 
			
		||||
                  [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>,
 | 
			
		||||
                  Requires<[IsThumb2, CarryDefIsUsed]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -293,7 +293,7 @@ multiclass T2I_adde_sube_irs<string opc, PatFrag opnode, bit Commutable = 0> {
 | 
			
		|||
                    let isCommutable = Commutable;
 | 
			
		||||
   }
 | 
			
		||||
   // shifted register
 | 
			
		||||
   def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
 | 
			
		||||
   def Srs : T2XI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
 | 
			
		||||
                  !strconcat(opc, "s.w $dst, $lhs, $rhs"),
 | 
			
		||||
                  [(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>,
 | 
			
		||||
                  Requires<[IsThumb2, CarryDefIsUsed]> {
 | 
			
		||||
| 
						 | 
				
			
			@ -306,11 +306,11 @@ multiclass T2I_adde_sube_irs<string opc, PatFrag opnode, bit Commutable = 0> {
 | 
			
		|||
let Defs = [CPSR] in {
 | 
			
		||||
multiclass T2I_rbin_s_is<string opc, PatFrag opnode> {
 | 
			
		||||
   // shifted imm
 | 
			
		||||
   def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s),
 | 
			
		||||
   def ri : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_imm:$lhs, cc_out:$s), IIC_iALU,
 | 
			
		||||
                 !strconcat(opc, "${s}.w $dst, $rhs, $lhs"),
 | 
			
		||||
                 [(set GPR:$dst, (opnode t2_so_imm:$lhs, GPR:$rhs))]>;
 | 
			
		||||
   // shifted register
 | 
			
		||||
   def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s),
 | 
			
		||||
   def rs : T2XI<(outs GPR:$dst), (ins GPR:$rhs, t2_so_reg:$lhs, cc_out:$s), IIC_iALU,
 | 
			
		||||
                 !strconcat(opc, "${s} $dst, $rhs, $lhs"),
 | 
			
		||||
                 [(set GPR:$dst, (opnode t2_so_reg:$lhs, GPR:$rhs))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -320,11 +320,11 @@ multiclass T2I_rbin_s_is<string opc, PatFrag opnode> {
 | 
			
		|||
//  rotate operation that produces a value.
 | 
			
		||||
multiclass T2I_sh_ir<string opc, PatFrag opnode> {
 | 
			
		||||
   // 5-bit imm
 | 
			
		||||
   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
 | 
			
		||||
   def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, ".w $dst, $lhs, $rhs",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, imm1_31:$rhs))]>;
 | 
			
		||||
   // register
 | 
			
		||||
   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
   def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                 opc, ".w $dst, $lhs, $rhs",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -335,15 +335,15 @@ multiclass T2I_sh_ir<string opc, PatFrag opnode> {
 | 
			
		|||
let Defs = [CPSR] in {
 | 
			
		||||
multiclass T2I_cmp_is<string opc, PatFrag opnode> {
 | 
			
		||||
   // shifted imm
 | 
			
		||||
   def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs),
 | 
			
		||||
   def ri : T2I<(outs), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
 | 
			
		||||
                opc, ".w $lhs, $rhs",
 | 
			
		||||
                [(opnode GPR:$lhs, t2_so_imm:$rhs)]>;
 | 
			
		||||
   // register
 | 
			
		||||
   def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
   def rr : T2I<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                opc, ".w $lhs, $rhs",
 | 
			
		||||
                [(opnode GPR:$lhs, GPR:$rhs)]>;
 | 
			
		||||
   // shifted register
 | 
			
		||||
   def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs),
 | 
			
		||||
   def rs : T2I<(outs), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
 | 
			
		||||
                opc, ".w $lhs, $rhs",
 | 
			
		||||
                [(opnode GPR:$lhs, t2_so_reg:$rhs)]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -351,42 +351,42 @@ multiclass T2I_cmp_is<string opc, PatFrag opnode> {
 | 
			
		|||
 | 
			
		||||
/// T2I_ld - Defines a set of (op r, {imm12|imm8|so_reg}) load patterns.
 | 
			
		||||
multiclass T2I_ld<string opc, PatFrag opnode> {
 | 
			
		||||
  def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr),
 | 
			
		||||
  def i12 : T2Ii12<(outs GPR:$dst), (ins t2addrmode_imm12:$addr), IIC_iLoad,
 | 
			
		||||
                   opc, ".w $dst, $addr",
 | 
			
		||||
                   [(set GPR:$dst, (opnode t2addrmode_imm12:$addr))]>;
 | 
			
		||||
  def i8  : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr),
 | 
			
		||||
  def i8  : T2Ii8 <(outs GPR:$dst), (ins t2addrmode_imm8:$addr), IIC_iLoad,
 | 
			
		||||
                   opc, " $dst, $addr",
 | 
			
		||||
                   [(set GPR:$dst, (opnode t2addrmode_imm8:$addr))]>;
 | 
			
		||||
  def s   : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr),
 | 
			
		||||
  def s   : T2Iso <(outs GPR:$dst), (ins t2addrmode_so_reg:$addr), IIC_iLoad,
 | 
			
		||||
                   opc, ".w $dst, $addr",
 | 
			
		||||
                   [(set GPR:$dst, (opnode t2addrmode_so_reg:$addr))]>;
 | 
			
		||||
  def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr),
 | 
			
		||||
  def pci : T2Ipc <(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoad,
 | 
			
		||||
                   opc, ".w $dst, $addr",
 | 
			
		||||
                   [(set GPR:$dst, (opnode (ARMWrapper tconstpool:$addr)))]>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// T2I_st - Defines a set of (op r, {imm12|imm8|so_reg}) store patterns.
 | 
			
		||||
multiclass T2I_st<string opc, PatFrag opnode> {
 | 
			
		||||
  def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr),
 | 
			
		||||
  def i12 : T2Ii12<(outs), (ins GPR:$src, t2addrmode_imm12:$addr), IIC_iStore,
 | 
			
		||||
                   opc, ".w $src, $addr",
 | 
			
		||||
                   [(opnode GPR:$src, t2addrmode_imm12:$addr)]>;
 | 
			
		||||
  def i8  : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr),
 | 
			
		||||
  def i8  : T2Ii8 <(outs), (ins GPR:$src, t2addrmode_imm8:$addr), IIC_iStore,
 | 
			
		||||
                   opc, " $src, $addr",
 | 
			
		||||
                   [(opnode GPR:$src, t2addrmode_imm8:$addr)]>;
 | 
			
		||||
  def s   : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr),
 | 
			
		||||
  def s   : T2Iso <(outs), (ins GPR:$src, t2addrmode_so_reg:$addr), IIC_iStore,
 | 
			
		||||
                   opc, ".w $src, $addr",
 | 
			
		||||
                   [(opnode GPR:$src, t2addrmode_so_reg:$addr)]>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// T2I_picld - Defines the PIC load pattern.
 | 
			
		||||
class T2I_picld<string opc, PatFrag opnode> :
 | 
			
		||||
      T2I<(outs GPR:$dst), (ins addrmodepc:$addr),
 | 
			
		||||
      T2I<(outs GPR:$dst), (ins addrmodepc:$addr), IIC_iLoad,
 | 
			
		||||
          !strconcat("${addr:label}:\n\t", opc), " $dst, $addr",
 | 
			
		||||
          [(set GPR:$dst, (opnode addrmodepc:$addr))]>;
 | 
			
		||||
 | 
			
		||||
/// T2I_picst - Defines the PIC store pattern.
 | 
			
		||||
class T2I_picst<string opc, PatFrag opnode> :
 | 
			
		||||
      T2I<(outs), (ins GPR:$src, addrmodepc:$addr),
 | 
			
		||||
      T2I<(outs), (ins GPR:$src, addrmodepc:$addr), IIC_iStore,
 | 
			
		||||
          !strconcat("${addr:label}:\n\t", opc), " $src, $addr",
 | 
			
		||||
          [(opnode GPR:$src, addrmodepc:$addr)]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -394,10 +394,10 @@ class T2I_picst<string opc, PatFrag opnode> :
 | 
			
		|||
/// T2I_unary_rrot - A unary operation with two forms: one whose operand is a
 | 
			
		||||
/// register and one whose operand is a register rotated by 8/16/24.
 | 
			
		||||
multiclass T2I_unary_rrot<string opc, PatFrag opnode> {
 | 
			
		||||
  def r     : T2I<(outs GPR:$dst), (ins GPR:$Src),
 | 
			
		||||
  def r     : T2I<(outs GPR:$dst), (ins GPR:$Src), IIC_iALU,
 | 
			
		||||
                  opc, ".w $dst, $Src",
 | 
			
		||||
                 [(set GPR:$dst, (opnode GPR:$Src))]>;
 | 
			
		||||
  def r_rot : T2I<(outs GPR:$dst), (ins GPR:$Src, i32imm:$rot),
 | 
			
		||||
  def r_rot : T2I<(outs GPR:$dst), (ins GPR:$Src, i32imm:$rot), IIC_iALU,
 | 
			
		||||
                  opc, ".w $dst, $Src, ror $rot",
 | 
			
		||||
                 [(set GPR:$dst, (opnode (rotr GPR:$Src, rot_imm:$rot)))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -405,11 +405,11 @@ multiclass T2I_unary_rrot<string opc, PatFrag opnode> {
 | 
			
		|||
/// T2I_bin_rrot - A binary operation with two forms: one whose operand is a
 | 
			
		||||
/// register and one whose operand is a register rotated by 8/16/24.
 | 
			
		||||
multiclass T2I_bin_rrot<string opc, PatFrag opnode> {
 | 
			
		||||
  def rr     : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS),
 | 
			
		||||
  def rr     : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS), IIC_iALU,
 | 
			
		||||
                  opc, " $dst, $LHS, $RHS",
 | 
			
		||||
                  [(set GPR:$dst, (opnode GPR:$LHS, GPR:$RHS))]>;
 | 
			
		||||
  def rr_rot : T2I<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, i32imm:$rot),
 | 
			
		||||
                  opc, " $dst, $LHS, $RHS, ror $rot",
 | 
			
		||||
                  IIC_iALU, opc, " $dst, $LHS, $RHS, ror $rot",
 | 
			
		||||
                  [(set GPR:$dst, (opnode GPR:$LHS,
 | 
			
		||||
                                          (rotr GPR:$RHS, rot_imm:$rot)))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -424,11 +424,11 @@ multiclass T2I_bin_rrot<string opc, PatFrag opnode> {
 | 
			
		|||
 | 
			
		||||
// LEApcrel - Load a pc-relative address into a register without offending the
 | 
			
		||||
// assembler.
 | 
			
		||||
def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p),
 | 
			
		||||
def t2LEApcrel : T2XI<(outs GPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALU,
 | 
			
		||||
                      "adr$p.w $dst, #$label", []>;
 | 
			
		||||
 | 
			
		||||
def t2LEApcrelJT : T2XI<(outs GPR:$dst),
 | 
			
		||||
                        (ins i32imm:$label, i32imm:$id, pred:$p),
 | 
			
		||||
                        (ins i32imm:$label, i32imm:$id, pred:$p), IIC_iALU,
 | 
			
		||||
                        "adr$p.w $dst, #${label}_${id:no_hash}", []>;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			@ -450,8 +450,8 @@ defm t2LDRSB : T2I_ld<"ldrsb", UnOpFrag<(sextloadi8  node:$Src)>>;
 | 
			
		|||
let mayLoad = 1 in {
 | 
			
		||||
// Load doubleword
 | 
			
		||||
def t2LDRDi8 : T2Ii8s4<(outs GPR:$dst), (ins t2addrmode_imm8s4:$addr),
 | 
			
		||||
                       "ldrd", " $dst, $addr", []>;
 | 
			
		||||
def t2LDRDpci : T2Ii8s4<(outs GPR:$dst), (ins i32imm:$addr),
 | 
			
		||||
                        IIC_iLoad, "ldrd", " $dst, $addr", []>;
 | 
			
		||||
def t2LDRDpci : T2Ii8s4<(outs GPR:$dst), (ins i32imm:$addr), IIC_iLoad,
 | 
			
		||||
                       "ldrd", " $dst, $addr", []>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -499,57 +499,57 @@ def : T2Pat<(extloadi16 (ARMWrapper tconstpool:$addr)),
 | 
			
		|||
let mayLoad = 1 in {
 | 
			
		||||
def t2LDR_PRE  : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                            (ins t2addrmode_imm8:$addr),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre, IIC_iLoad,
 | 
			
		||||
                            "ldr", " $dst, $addr!", "$addr.base = $base_wb",
 | 
			
		||||
                            []>;
 | 
			
		||||
 | 
			
		||||
def t2LDR_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost, IIC_iLoad,
 | 
			
		||||
                           "ldr", " $dst, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
                            []>;
 | 
			
		||||
 | 
			
		||||
def t2LDRB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                            (ins t2addrmode_imm8:$addr),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre, IIC_iLoad,
 | 
			
		||||
                            "ldrb", " $dst, $addr!", "$addr.base = $base_wb",
 | 
			
		||||
                            []>;
 | 
			
		||||
def t2LDRB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost, IIC_iLoad,
 | 
			
		||||
                          "ldrb", " $dst, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
                            []>;
 | 
			
		||||
 | 
			
		||||
def t2LDRH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                            (ins t2addrmode_imm8:$addr),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre, IIC_iLoad,
 | 
			
		||||
                            "ldrh", " $dst, $addr!", "$addr.base = $base_wb",
 | 
			
		||||
                            []>;
 | 
			
		||||
def t2LDRH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost, IIC_iLoad,
 | 
			
		||||
                          "ldrh", " $dst, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
                            []>;
 | 
			
		||||
 | 
			
		||||
def t2LDRSB_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                            (ins t2addrmode_imm8:$addr),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre, IIC_iLoad,
 | 
			
		||||
                            "ldrsb", " $dst, $addr!", "$addr.base = $base_wb",
 | 
			
		||||
                            []>;
 | 
			
		||||
def t2LDRSB_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost, IIC_iLoad,
 | 
			
		||||
                         "ldrsb", " $dst, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
                            []>;
 | 
			
		||||
 | 
			
		||||
def t2LDRSH_PRE : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                            (ins t2addrmode_imm8:$addr),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre, IIC_iLoad,
 | 
			
		||||
                            "ldrsh", " $dst, $addr!", "$addr.base = $base_wb",
 | 
			
		||||
                            []>;
 | 
			
		||||
def t2LDRSH_POST : T2Iidxldst<(outs GPR:$dst, GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost, IIC_iLoad,
 | 
			
		||||
                         "ldrsh", " $dst, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
                            []>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -561,48 +561,48 @@ defm t2STRH  : T2I_st<"strh", BinOpFrag<(truncstorei16 node:$LHS, node:$RHS)>>;
 | 
			
		|||
 | 
			
		||||
// Store doubleword
 | 
			
		||||
let mayLoad = 1 in
 | 
			
		||||
def t2STRDi8 : T2Ii8s4<(outs), (ins GPR:$src, t2addrmode_imm8s4:$addr),
 | 
			
		||||
def t2STRDi8 : T2Ii8s4<(outs), (ins GPR:$src, t2addrmode_imm8s4:$addr),  IIC_iStore,
 | 
			
		||||
                        "strd", " $src, $addr", []>;
 | 
			
		||||
 | 
			
		||||
// Indexed stores
 | 
			
		||||
def t2STR_PRE  : T2Iidxldst<(outs GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre, IIC_iStore,
 | 
			
		||||
                          "str", " $src, [$base, $offset]!", "$base = $base_wb",
 | 
			
		||||
             [(set GPR:$base_wb,
 | 
			
		||||
                   (pre_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
 | 
			
		||||
 | 
			
		||||
def t2STR_POST : T2Iidxldst<(outs GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost, IIC_iStore,
 | 
			
		||||
                           "str", " $src, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
             [(set GPR:$base_wb,
 | 
			
		||||
                   (post_store GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
 | 
			
		||||
 | 
			
		||||
def t2STRH_PRE  : T2Iidxldst<(outs GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre, IIC_iStore,
 | 
			
		||||
                         "strh", " $src, [$base, $offset]!", "$base = $base_wb",
 | 
			
		||||
        [(set GPR:$base_wb,
 | 
			
		||||
              (pre_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
 | 
			
		||||
 | 
			
		||||
def t2STRH_POST : T2Iidxldst<(outs GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost, IIC_iStore,
 | 
			
		||||
                          "strh", " $src, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
       [(set GPR:$base_wb,
 | 
			
		||||
             (post_truncsti16 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
 | 
			
		||||
 | 
			
		||||
def t2STRB_PRE  : T2Iidxldst<(outs GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePre, IIC_iStore,
 | 
			
		||||
                         "strb", " $src, [$base, $offset]!", "$base = $base_wb",
 | 
			
		||||
         [(set GPR:$base_wb,
 | 
			
		||||
               (pre_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
 | 
			
		||||
 | 
			
		||||
def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb),
 | 
			
		||||
                            (ins GPR:$src, GPR:$base, t2am_imm8_offset:$offset),
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost,
 | 
			
		||||
                            AddrModeT2_i8, IndexModePost, IIC_iStore,
 | 
			
		||||
                          "strb", " $src, [$base], $offset", "$base = $base_wb",
 | 
			
		||||
        [(set GPR:$base_wb,
 | 
			
		||||
              (post_truncsti8 GPR:$src, GPR:$base, t2am_imm8_offset:$offset))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -617,34 +617,34 @@ def t2STRB_POST : T2Iidxldst<(outs GPR:$base_wb),
 | 
			
		|||
let mayLoad = 1 in
 | 
			
		||||
def t2LDM : T2XI<(outs),
 | 
			
		||||
                 (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
 | 
			
		||||
                 "ldm${addr:submode}${p} $addr, $dst1", []>;
 | 
			
		||||
                  IIC_iLoad, "ldm${addr:submode}${p} $addr, $dst1", []>;
 | 
			
		||||
 | 
			
		||||
let mayStore = 1 in
 | 
			
		||||
def t2STM : T2XI<(outs),
 | 
			
		||||
                 (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops),
 | 
			
		||||
                 "stm${addr:submode}${p} $addr, $src1", []>;
 | 
			
		||||
                  IIC_iStore, "stm${addr:submode}${p} $addr, $src1", []>;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
//  Move Instructions.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
let neverHasSideEffects = 1 in
 | 
			
		||||
def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def t2MOVr : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
                   "mov", ".w $dst, $src", []>;
 | 
			
		||||
 | 
			
		||||
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
 | 
			
		||||
def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src),
 | 
			
		||||
def t2MOVi : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iALU,
 | 
			
		||||
                   "mov", ".w $dst, $src",
 | 
			
		||||
                   [(set GPR:$dst, t2_so_imm:$src)]>;
 | 
			
		||||
 | 
			
		||||
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
 | 
			
		||||
def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src),
 | 
			
		||||
def t2MOVi16 : T2I<(outs GPR:$dst), (ins i32imm:$src), IIC_iALU,
 | 
			
		||||
                   "movw", " $dst, $src",
 | 
			
		||||
                   [(set GPR:$dst, imm0_65535:$src)]>;
 | 
			
		||||
 | 
			
		||||
// FIXME: Also available in ARM mode.
 | 
			
		||||
let Constraints = "$src = $dst" in
 | 
			
		||||
def t2MOVTi16 : T2sI<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
 | 
			
		||||
def t2MOVTi16 : T2sI<(outs GPR:$dst), (ins GPR:$src, i32imm:$imm), IIC_iALU,
 | 
			
		||||
                     "movt", " $dst, $imm",
 | 
			
		||||
                     [(set GPR:$dst,
 | 
			
		||||
                           (or (and GPR:$src, 0xffff), t2_lo16AllZero:$imm))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -720,15 +720,15 @@ defm t2LSR  : T2I_sh_ir<"lsr", BinOpFrag<(srl  node:$LHS, node:$RHS)>>;
 | 
			
		|||
defm t2ASR  : T2I_sh_ir<"asr", BinOpFrag<(sra  node:$LHS, node:$RHS)>>;
 | 
			
		||||
defm t2ROR  : T2I_sh_ir<"ror", BinOpFrag<(rotr node:$LHS, node:$RHS)>>;
 | 
			
		||||
 | 
			
		||||
def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def t2MOVrx : T2sI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
                   "rrx", ".w $dst, $src",
 | 
			
		||||
                   [(set GPR:$dst, (ARMrrx GPR:$src))]>;
 | 
			
		||||
 | 
			
		||||
let Defs = [CPSR] in {
 | 
			
		||||
def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def t2MOVsrl_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
                         "lsrs.w $dst, $src, #1",
 | 
			
		||||
                         [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>;
 | 
			
		||||
def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def t2MOVsra_flag : T2XI<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
                         "asrs.w $dst, $src, #1",
 | 
			
		||||
                         [(set GPR:$dst, (ARMsra_flag GPR:$src))]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -744,7 +744,7 @@ defm t2EOR  : T2I_bin_w_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
 | 
			
		|||
defm t2BIC  : T2I_bin_w_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
 | 
			
		||||
 | 
			
		||||
let Constraints = "$src = $dst" in
 | 
			
		||||
def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
 | 
			
		||||
def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), IIC_iALU,
 | 
			
		||||
                "bfc", " $dst, $imm",
 | 
			
		||||
                [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -754,15 +754,15 @@ def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
 | 
			
		|||
defm t2ORN  : T2I_bin_irs<"orn", BinOpFrag<(or  node:$LHS, (not node:$RHS))>>;
 | 
			
		||||
*/
 | 
			
		||||
// FIXME: Disable this pattern on Darwin to workaround an assembler bug.
 | 
			
		||||
def t2ORNri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs),
 | 
			
		||||
def t2ORNri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
 | 
			
		||||
                   "orn", " $dst, $lhs, $rhs",
 | 
			
		||||
                   [(set GPR:$dst, (or GPR:$lhs, (not t2_so_imm:$rhs)))]>,
 | 
			
		||||
                   Requires<[IsThumb2, IsNotDarwin]>;
 | 
			
		||||
 | 
			
		||||
def t2ORNrr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
 | 
			
		||||
def t2ORNrr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
 | 
			
		||||
                   "orn", " $dst, $lhs, $rhs",
 | 
			
		||||
                   [(set GPR:$dst, (or GPR:$lhs, (not GPR:$rhs)))]>;
 | 
			
		||||
def t2ORNrs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs),
 | 
			
		||||
def t2ORNrs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
 | 
			
		||||
                   "orn", " $dst, $lhs, $rhs",
 | 
			
		||||
                   [(set GPR:$dst, (or GPR:$lhs, (not t2_so_reg:$rhs)))]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -786,80 +786,80 @@ def : T2Pat<(t2_so_imm_not:$src),
 | 
			
		|||
//  Multiply Instructions.
 | 
			
		||||
//
 | 
			
		||||
let isCommutable = 1 in
 | 
			
		||||
def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
def t2MUL: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                "mul", " $dst, $a, $b",
 | 
			
		||||
                [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
 | 
			
		||||
 | 
			
		||||
def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		||||
def t2MLA: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
 | 
			
		||||
		"mla", " $dst, $a, $b, $c",
 | 
			
		||||
		[(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
 | 
			
		||||
 | 
			
		||||
def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		||||
def t2MLS: T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
 | 
			
		||||
		"mls", " $dst, $a, $b, $c",
 | 
			
		||||
                [(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>;
 | 
			
		||||
 | 
			
		||||
// Extra precision multiplies with low / high results
 | 
			
		||||
let neverHasSideEffects = 1 in {
 | 
			
		||||
let isCommutable = 1 in {
 | 
			
		||||
def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
def t2SMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                   "smull", " $ldst, $hdst, $a, $b", []>;
 | 
			
		||||
 | 
			
		||||
def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
def t2UMULL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                   "umull", " $ldst, $hdst, $a, $b", []>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Multiply + accumulate
 | 
			
		||||
def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
def t2SMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                  "smlal", " $ldst, $hdst, $a, $b", []>;
 | 
			
		||||
 | 
			
		||||
def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
def t2UMLAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                  "umlal", " $ldst, $hdst, $a, $b", []>;
 | 
			
		||||
 | 
			
		||||
def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
def t2UMAAL : T2I<(outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                  "umaal", " $ldst, $hdst, $a, $b", []>;
 | 
			
		||||
} // neverHasSideEffects
 | 
			
		||||
 | 
			
		||||
// Most significant word multiply
 | 
			
		||||
def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
def t2SMMUL : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
                  "smmul", " $dst, $a, $b",
 | 
			
		||||
                  [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>;
 | 
			
		||||
 | 
			
		||||
def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		||||
def t2SMMLA : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
 | 
			
		||||
                  "smmla", " $dst, $a, $b, $c",
 | 
			
		||||
                  [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
 | 
			
		||||
def t2SMMLS : T2I <(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), IIC_iALU,
 | 
			
		||||
                   "smmls", " $dst, $a, $b, $c",
 | 
			
		||||
                   [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>;
 | 
			
		||||
 | 
			
		||||
multiclass T2I_smul<string opc, PatFrag opnode> {
 | 
			
		||||
  def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
  def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "bb"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
 | 
			
		||||
                                      (sext_inreg GPR:$b, i16)))]>;
 | 
			
		||||
 | 
			
		||||
  def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
  def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "bt"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
 | 
			
		||||
                                      (sra GPR:$b, (i32 16))))]>;
 | 
			
		||||
 | 
			
		||||
  def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
  def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "tb"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
 | 
			
		||||
                                      (sext_inreg GPR:$b, i16)))]>;
 | 
			
		||||
 | 
			
		||||
  def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
  def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "tt"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
 | 
			
		||||
                                      (sra GPR:$b, (i32 16))))]>;
 | 
			
		||||
 | 
			
		||||
  def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
  def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "wb"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (sra (opnode GPR:$a,
 | 
			
		||||
                                    (sext_inreg GPR:$b, i16)), (i32 16)))]>;
 | 
			
		||||
 | 
			
		||||
  def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b),
 | 
			
		||||
  def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "wt"), " $dst, $a, $b",
 | 
			
		||||
              [(set GPR:$dst, (sra (opnode GPR:$a,
 | 
			
		||||
                                    (sra GPR:$b, (i32 16))), (i32 16)))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -867,33 +867,33 @@ multiclass T2I_smul<string opc, PatFrag opnode> {
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
multiclass T2I_smla<string opc, PatFrag opnode> {
 | 
			
		||||
  def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
  def BB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "bb"), " $dst, $a, $b, $acc",
 | 
			
		||||
              [(set GPR:$dst, (add GPR:$acc,
 | 
			
		||||
                               (opnode (sext_inreg GPR:$a, i16),
 | 
			
		||||
                                       (sext_inreg GPR:$b, i16))))]>;
 | 
			
		||||
 | 
			
		||||
  def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
  def BT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
 | 
			
		||||
             !strconcat(opc, "bt"), " $dst, $a, $b, $acc",
 | 
			
		||||
             [(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
 | 
			
		||||
                                                    (sra GPR:$b, (i32 16)))))]>;
 | 
			
		||||
 | 
			
		||||
  def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
  def TB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "tb"), " $dst, $a, $b, $acc",
 | 
			
		||||
              [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
 | 
			
		||||
                                                 (sext_inreg GPR:$b, i16))))]>;
 | 
			
		||||
 | 
			
		||||
  def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
  def TT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "tt"), " $dst, $a, $b, $acc",
 | 
			
		||||
             [(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
 | 
			
		||||
                                                    (sra GPR:$b, (i32 16)))))]>;
 | 
			
		||||
 | 
			
		||||
  def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
  def WB : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "wb"), " $dst, $a, $b, $acc",
 | 
			
		||||
              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
 | 
			
		||||
                                       (sext_inreg GPR:$b, i16)), (i32 16))))]>;
 | 
			
		||||
 | 
			
		||||
  def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
 | 
			
		||||
  def WT : T2I<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), IIC_iALU,
 | 
			
		||||
              !strconcat(opc, "wt"), " $dst, $a, $b, $acc",
 | 
			
		||||
              [(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
 | 
			
		||||
                                         (sra GPR:$b, (i32 16))), (i32 16))))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -910,15 +910,15 @@ defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
 | 
			
		|||
//  Misc. Arithmetic Instructions.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def t2CLZ : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
                "clz", " $dst, $src",
 | 
			
		||||
                [(set GPR:$dst, (ctlz GPR:$src))]>;
 | 
			
		||||
 | 
			
		||||
def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def t2REV : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
                "rev", ".w $dst, $src",
 | 
			
		||||
                [(set GPR:$dst, (bswap GPR:$src))]>;
 | 
			
		||||
 | 
			
		||||
def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
                "rev16", ".w $dst, $src",
 | 
			
		||||
                [(set GPR:$dst,
 | 
			
		||||
                    (or (and (srl GPR:$src, (i32 8)), 0xFF),
 | 
			
		||||
| 
						 | 
				
			
			@ -926,7 +926,7 @@ def t2REV16 : T2I<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		|||
                            (or (and (srl GPR:$src, (i32 8)), 0xFF0000),
 | 
			
		||||
                                (and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>;
 | 
			
		||||
 | 
			
		||||
def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		||||
def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
 | 
			
		||||
                 "revsh", ".w $dst, $src",
 | 
			
		||||
                 [(set GPR:$dst,
 | 
			
		||||
                    (sext_inreg
 | 
			
		||||
| 
						 | 
				
			
			@ -934,7 +934,7 @@ def t2REVSH : T2I<(outs GPR:$dst), (ins GPR:$src),
 | 
			
		|||
                          (shl GPR:$src, (i32 8))), i16))]>;
 | 
			
		||||
 | 
			
		||||
def t2PKHBT : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
 | 
			
		||||
                  "pkhbt", " $dst, $src1, $src2, LSL $shamt",
 | 
			
		||||
                  IIC_iALU, "pkhbt", " $dst, $src1, $src2, LSL $shamt",
 | 
			
		||||
                  [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
 | 
			
		||||
                                      (and (shl GPR:$src2, (i32 imm:$shamt)),
 | 
			
		||||
                                           0xFFFF0000)))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -946,7 +946,7 @@ def : T2Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
 | 
			
		|||
            (t2PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
 | 
			
		||||
 | 
			
		||||
def t2PKHTB : T2I<(outs GPR:$dst), (ins GPR:$src1, GPR:$src2, i32imm:$shamt),
 | 
			
		||||
                  "pkhtb", " $dst, $src1, $src2, ASR $shamt",
 | 
			
		||||
                  IIC_iALU, "pkhtb", " $dst, $src1, $src2, ASR $shamt",
 | 
			
		||||
                  [(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
 | 
			
		||||
                                      (and (sra GPR:$src2, imm16_31:$shamt),
 | 
			
		||||
                                           0xFFFF)))]>;
 | 
			
		||||
| 
						 | 
				
			
			@ -992,27 +992,27 @@ defm t2TEQ  : T2I_cmp_is<"teq",
 | 
			
		|||
// Conditional moves
 | 
			
		||||
// FIXME: should be able to write a pattern for ARMcmov, but can't use
 | 
			
		||||
// a two-value operand where a dag node expects two operands. :( 
 | 
			
		||||
def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true),
 | 
			
		||||
def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true), IIC_iALU,
 | 
			
		||||
                   "mov", ".w $dst, $true",
 | 
			
		||||
      [/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
 | 
			
		||||
                RegConstraint<"$false = $dst">;
 | 
			
		||||
 | 
			
		||||
def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true),
 | 
			
		||||
def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true), IIC_iALU,
 | 
			
		||||
                   "mov", ".w $dst, $true",
 | 
			
		||||
[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
 | 
			
		||||
                   RegConstraint<"$false = $dst">;
 | 
			
		||||
 | 
			
		||||
def t2MOVCClsl : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
 | 
			
		||||
                   "lsl", ".w $dst, $true, $rhs", []>,
 | 
			
		||||
                   IIC_iALU, "lsl", ".w $dst, $true, $rhs", []>,
 | 
			
		||||
                   RegConstraint<"$false = $dst">;
 | 
			
		||||
def t2MOVCClsr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
 | 
			
		||||
                   "lsr", ".w $dst, $true, $rhs", []>,
 | 
			
		||||
                   IIC_iALU, "lsr", ".w $dst, $true, $rhs", []>,
 | 
			
		||||
                   RegConstraint<"$false = $dst">;
 | 
			
		||||
def t2MOVCCasr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
 | 
			
		||||
                   "asr", ".w $dst, $true, $rhs", []>,
 | 
			
		||||
                   IIC_iALU, "asr", ".w $dst, $true, $rhs", []>,
 | 
			
		||||
                   RegConstraint<"$false = $dst">;
 | 
			
		||||
def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
 | 
			
		||||
                   "ror", ".w $dst, $true, $rhs", []>,
 | 
			
		||||
                   IIC_iALU, "ror", ".w $dst, $true, $rhs", []>,
 | 
			
		||||
                   RegConstraint<"$false = $dst">;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			@ -1022,7 +1022,7 @@ def t2MOVCCror : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true, i32imm:$rhs),
 | 
			
		|||
// __aeabi_read_tp preserves the registers r1-r3.
 | 
			
		||||
let isCall = 1,
 | 
			
		||||
  Defs = [R0, R12, LR, CPSR] in {
 | 
			
		||||
  def t2TPsoft : T2XI<(outs), (ins),
 | 
			
		||||
  def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
 | 
			
		||||
                     "bl __aeabi_read_tp",
 | 
			
		||||
                     [(set R0, ARMthread_pointer)]>;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1038,12 +1038,12 @@ let isCall = 1,
 | 
			
		|||
let isReturn = 1, isTerminator = 1, mayLoad = 1 in
 | 
			
		||||
  def t2LDM_RET : T2XI<(outs),
 | 
			
		||||
                    (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
 | 
			
		||||
                    "ldm${addr:submode}${p} $addr, $dst1",
 | 
			
		||||
                    IIC_iLoad, "ldm${addr:submode}${p} $addr, $dst1",
 | 
			
		||||
                    []>;
 | 
			
		||||
 | 
			
		||||
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
 | 
			
		||||
let isPredicable = 1 in
 | 
			
		||||
def t2B   : T2XI<(outs), (ins brtarget:$target),
 | 
			
		||||
def t2B   : T2XI<(outs), (ins brtarget:$target), IIC_Br,
 | 
			
		||||
                 "b.w $target",
 | 
			
		||||
                 [(br bb:$target)]>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1051,19 +1051,19 @@ let isNotDuplicable = 1, isIndirectBranch = 1 in {
 | 
			
		|||
def t2BR_JT :
 | 
			
		||||
    T2JTI<(outs),
 | 
			
		||||
          (ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
 | 
			
		||||
          "mov pc, $target\n$jt",
 | 
			
		||||
           IIC_Br, "mov pc, $target\n$jt",
 | 
			
		||||
          [(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]>;
 | 
			
		||||
 | 
			
		||||
// FIXME: Add a non-pc based case that can be predicated.
 | 
			
		||||
def t2TBB :
 | 
			
		||||
    T2JTI<(outs),
 | 
			
		||||
        (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
 | 
			
		||||
        "tbb $index\n$jt", []>;
 | 
			
		||||
         IIC_Br, "tbb $index\n$jt", []>;
 | 
			
		||||
 | 
			
		||||
def t2TBH :
 | 
			
		||||
    T2JTI<(outs),
 | 
			
		||||
        (ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
 | 
			
		||||
        "tbh $index\n$jt", []>;
 | 
			
		||||
         IIC_Br, "tbh $index\n$jt", []>;
 | 
			
		||||
} // isNotDuplicable, isIndirectBranch
 | 
			
		||||
 | 
			
		||||
} // isBranch, isTerminator, isBarrier
 | 
			
		||||
| 
						 | 
				
			
			@ -1071,14 +1071,14 @@ def t2TBH :
 | 
			
		|||
// FIXME: should be able to write a pattern for ARMBrcond, but can't use
 | 
			
		||||
// a two-value operand where a dag node expects two operands. :(
 | 
			
		||||
let isBranch = 1, isTerminator = 1 in
 | 
			
		||||
def t2Bcc : T2I<(outs), (ins brtarget:$target), 
 | 
			
		||||
def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
 | 
			
		||||
                "b", ".w $target",
 | 
			
		||||
                [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// IT block
 | 
			
		||||
def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
 | 
			
		||||
                    AddrModeNone, Size2Bytes,
 | 
			
		||||
                    AddrModeNone, Size2Bytes,  IIC_iALU,
 | 
			
		||||
                    "it$mask $cc", "", []>;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,20 +36,20 @@ def arm_fmdrr  : SDNode<"ARMISD::FMDRR",  SDT_FMDRR>;
 | 
			
		|||
 | 
			
		||||
let canFoldAsLoad = 1 in {
 | 
			
		||||
def FLDD  : ADI5<0b1101, 0b01, (outs DPR:$dst), (ins addrmode5:$addr),
 | 
			
		||||
                 "fldd", " $dst, $addr",
 | 
			
		||||
                 IIC_fpLoad, "fldd", " $dst, $addr",
 | 
			
		||||
                 [(set DPR:$dst, (load addrmode5:$addr))]>;
 | 
			
		||||
 | 
			
		||||
def FLDS  : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
 | 
			
		||||
                 "flds", " $dst, $addr",
 | 
			
		||||
                 IIC_fpLoad, "flds", " $dst, $addr",
 | 
			
		||||
                 [(set SPR:$dst, (load addrmode5:$addr))]>;
 | 
			
		||||
} // canFoldAsLoad
 | 
			
		||||
 | 
			
		||||
def FSTD  : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
 | 
			
		||||
                 "fstd", " $src, $addr",
 | 
			
		||||
                 IIC_fpStore, "fstd", " $src, $addr",
 | 
			
		||||
                 [(store DPR:$src, addrmode5:$addr)]>;
 | 
			
		||||
 | 
			
		||||
def FSTS  : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
 | 
			
		||||
                 "fsts", " $src, $addr",
 | 
			
		||||
                 IIC_fpStore, "fsts", " $src, $addr",
 | 
			
		||||
                 [(store SPR:$src, addrmode5:$addr)]>;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			@ -58,14 +58,14 @@ def FSTS  : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
 | 
			
		|||
 | 
			
		||||
let mayLoad = 1 in {
 | 
			
		||||
def FLDMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
 | 
			
		||||
                           variable_ops),
 | 
			
		||||
                           variable_ops), IIC_fpLoad,
 | 
			
		||||
                  "fldm${addr:submode}d${p} ${addr:base}, $dst1",
 | 
			
		||||
                  []> {
 | 
			
		||||
  let Inst{20} = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
 | 
			
		||||
                           variable_ops),
 | 
			
		||||
                           variable_ops), IIC_fpLoad, 
 | 
			
		||||
                  "fldm${addr:submode}s${p} ${addr:base}, $dst1",
 | 
			
		||||
                  []> {
 | 
			
		||||
  let Inst{20} = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -74,14 +74,14 @@ def FLDMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$dst1,
 | 
			
		|||
 | 
			
		||||
let mayStore = 1 in {
 | 
			
		||||
def FSTMD : AXDI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
 | 
			
		||||
                           variable_ops),
 | 
			
		||||
                           variable_ops), IIC_fpStore,
 | 
			
		||||
                 "fstm${addr:submode}d${p} ${addr:base}, $src1",
 | 
			
		||||
                 []> {
 | 
			
		||||
  let Inst{20} = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
 | 
			
		||||
                           variable_ops),
 | 
			
		||||
                           variable_ops), IIC_fpStore,
 | 
			
		||||
                 "fstm${addr:submode}s${p} ${addr:base}, $src1",
 | 
			
		||||
                 []> {
 | 
			
		||||
  let Inst{20} = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,48 +95,48 @@ def FSTMS : AXSI5<(outs), (ins addrmode5:$addr, pred:$p, reglist:$src1,
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
def FADDD  : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
 | 
			
		||||
                 "faddd", " $dst, $a, $b",
 | 
			
		||||
                 IIC_fpALU, "faddd", " $dst, $a, $b",
 | 
			
		||||
                 [(set DPR:$dst, (fadd DPR:$a, DPR:$b))]>;
 | 
			
		||||
 | 
			
		||||
def FADDS  : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
 | 
			
		||||
                  "fadds", " $dst, $a, $b",
 | 
			
		||||
                  IIC_fpALU, "fadds", " $dst, $a, $b",
 | 
			
		||||
                  [(set SPR:$dst, (fadd SPR:$a, SPR:$b))]>;
 | 
			
		||||
 | 
			
		||||
// These are encoded as unary instructions.
 | 
			
		||||
let Defs = [FPSCR] in {
 | 
			
		||||
def FCMPED : ADuI<0b11101011, 0b0100, 0b1100, (outs), (ins DPR:$a, DPR:$b),
 | 
			
		||||
                 "fcmped", " $a, $b",
 | 
			
		||||
                 IIC_fpALU, "fcmped", " $a, $b",
 | 
			
		||||
                 [(arm_cmpfp DPR:$a, DPR:$b)]>;
 | 
			
		||||
 | 
			
		||||
def FCMPES : ASuI<0b11101011, 0b0100, 0b1100, (outs), (ins SPR:$a, SPR:$b),
 | 
			
		||||
                 "fcmpes", " $a, $b",
 | 
			
		||||
                 IIC_fpALU, "fcmpes", " $a, $b",
 | 
			
		||||
                 [(arm_cmpfp SPR:$a, SPR:$b)]>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FDIVD  : ADbI<0b11101000, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
 | 
			
		||||
                 "fdivd", " $dst, $a, $b",
 | 
			
		||||
                 IIC_fpALU, "fdivd", " $dst, $a, $b",
 | 
			
		||||
                 [(set DPR:$dst, (fdiv DPR:$a, DPR:$b))]>;
 | 
			
		||||
 | 
			
		||||
def FDIVS  : ASbI<0b11101000, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
 | 
			
		||||
                 "fdivs", " $dst, $a, $b",
 | 
			
		||||
                 IIC_fpALU, "fdivs", " $dst, $a, $b",
 | 
			
		||||
                 [(set SPR:$dst, (fdiv SPR:$a, SPR:$b))]>;
 | 
			
		||||
 | 
			
		||||
def FMULD  : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
 | 
			
		||||
                 "fmuld", " $dst, $a, $b",
 | 
			
		||||
                 IIC_fpALU, "fmuld", " $dst, $a, $b",
 | 
			
		||||
                 [(set DPR:$dst, (fmul DPR:$a, DPR:$b))]>;
 | 
			
		||||
 | 
			
		||||
def FMULS  : ASbIn<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
 | 
			
		||||
                  "fmuls", " $dst, $a, $b",
 | 
			
		||||
                  IIC_fpALU, "fmuls", " $dst, $a, $b",
 | 
			
		||||
                  [(set SPR:$dst, (fmul SPR:$a, SPR:$b))]>;
 | 
			
		||||
                 
 | 
			
		||||
def FNMULD  : ADbI<0b11100010, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
 | 
			
		||||
                  "fnmuld", " $dst, $a, $b",
 | 
			
		||||
                  IIC_fpALU, "fnmuld", " $dst, $a, $b",
 | 
			
		||||
                  [(set DPR:$dst, (fneg (fmul DPR:$a, DPR:$b)))]> {
 | 
			
		||||
  let Inst{6} = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FNMULS  : ASbI<0b11100010, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
 | 
			
		||||
                  "fnmuls", " $dst, $a, $b",
 | 
			
		||||
                  IIC_fpALU, "fnmuls", " $dst, $a, $b",
 | 
			
		||||
                  [(set SPR:$dst, (fneg (fmul SPR:$a, SPR:$b)))]> {
 | 
			
		||||
  let Inst{6} = 1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -149,13 +149,13 @@ def : Pat<(fmul (fneg SPR:$a), SPR:$b),
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
def FSUBD  : ADbI<0b11100011, (outs DPR:$dst), (ins DPR:$a, DPR:$b),
 | 
			
		||||
                 "fsubd", " $dst, $a, $b",
 | 
			
		||||
                 IIC_fpALU, "fsubd", " $dst, $a, $b",
 | 
			
		||||
                 [(set DPR:$dst, (fsub DPR:$a, DPR:$b))]> {
 | 
			
		||||
  let Inst{6} = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FSUBS  : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
 | 
			
		||||
                  "fsubs", " $dst, $a, $b",
 | 
			
		||||
                  IIC_fpALU, "fsubs", " $dst, $a, $b",
 | 
			
		||||
                  [(set SPR:$dst, (fsub SPR:$a, SPR:$b))]> {
 | 
			
		||||
  let Inst{6} = 1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -165,30 +165,30 @@ def FSUBS  : ASbIn<0b11100011, (outs SPR:$dst), (ins SPR:$a, SPR:$b),
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
def FABSD  : ADuI<0b11101011, 0b0000, 0b1100, (outs DPR:$dst), (ins DPR:$a),
 | 
			
		||||
                 "fabsd", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "fabsd", " $dst, $a",
 | 
			
		||||
                 [(set DPR:$dst, (fabs DPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
def FABSS  : ASuIn<0b11101011, 0b0000, 0b1100, (outs SPR:$dst), (ins SPR:$a),
 | 
			
		||||
                  "fabss", " $dst, $a",
 | 
			
		||||
                  IIC_fpALU, "fabss", " $dst, $a",
 | 
			
		||||
                  [(set SPR:$dst, (fabs SPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
let Defs = [FPSCR] in {
 | 
			
		||||
def FCMPEZD : ADuI<0b11101011, 0b0101, 0b1100, (outs), (ins DPR:$a),
 | 
			
		||||
                  "fcmpezd", " $a",
 | 
			
		||||
                  IIC_fpALU, "fcmpezd", " $a",
 | 
			
		||||
                  [(arm_cmpfp0 DPR:$a)]>;
 | 
			
		||||
 | 
			
		||||
def FCMPEZS : ASuI<0b11101011, 0b0101, 0b1100, (outs), (ins SPR:$a),
 | 
			
		||||
                  "fcmpezs", " $a",
 | 
			
		||||
                  IIC_fpALU, "fcmpezs", " $a",
 | 
			
		||||
                  [(arm_cmpfp0 SPR:$a)]>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FCVTDS : ASuI<0b11101011, 0b0111, 0b1100, (outs DPR:$dst), (ins SPR:$a),
 | 
			
		||||
                 "fcvtds", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "fcvtds", " $dst, $a",
 | 
			
		||||
                 [(set DPR:$dst, (fextend SPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
// Special case encoding: bits 11-8 is 0b1011.
 | 
			
		||||
def FCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm,
 | 
			
		||||
                   "fcvtsd", " $dst, $a",
 | 
			
		||||
                   IIC_fpALU, "fcvtsd", " $dst, $a",
 | 
			
		||||
                   [(set SPR:$dst, (fround DPR:$a))]> {
 | 
			
		||||
  let Inst{27-23} = 0b11101;
 | 
			
		||||
  let Inst{21-16} = 0b110111;
 | 
			
		||||
| 
						 | 
				
			
			@ -198,26 +198,26 @@ def FCVTSD : VFPAI<(outs SPR:$dst), (ins DPR:$a), VFPUnaryFrm,
 | 
			
		|||
 | 
			
		||||
let neverHasSideEffects = 1 in {
 | 
			
		||||
def FCPYD  : ADuI<0b11101011, 0b0000, 0b0100, (outs DPR:$dst), (ins DPR:$a),
 | 
			
		||||
                 "fcpyd", " $dst, $a", []>;
 | 
			
		||||
                 IIC_fpALU, "fcpyd", " $dst, $a", []>;
 | 
			
		||||
 | 
			
		||||
def FCPYS  : ASuI<0b11101011, 0b0000, 0b0100, (outs SPR:$dst), (ins SPR:$a),
 | 
			
		||||
                 "fcpys", " $dst, $a", []>;
 | 
			
		||||
                 IIC_fpALU, "fcpys", " $dst, $a", []>;
 | 
			
		||||
} // neverHasSideEffects
 | 
			
		||||
 | 
			
		||||
def FNEGD  : ADuI<0b11101011, 0b0001, 0b0100, (outs DPR:$dst), (ins DPR:$a),
 | 
			
		||||
                 "fnegd", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "fnegd", " $dst, $a",
 | 
			
		||||
                 [(set DPR:$dst, (fneg DPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
def FNEGS  : ASuIn<0b11101011, 0b0001, 0b0100, (outs SPR:$dst), (ins SPR:$a),
 | 
			
		||||
                  "fnegs", " $dst, $a",
 | 
			
		||||
                  IIC_fpALU, "fnegs", " $dst, $a",
 | 
			
		||||
                  [(set SPR:$dst, (fneg SPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
def FSQRTD  : ADuI<0b11101011, 0b0001, 0b1100, (outs DPR:$dst), (ins DPR:$a),
 | 
			
		||||
                 "fsqrtd", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "fsqrtd", " $dst, $a",
 | 
			
		||||
                 [(set DPR:$dst, (fsqrt DPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
def FSQRTS  : ASuI<0b11101011, 0b0001, 0b1100, (outs SPR:$dst), (ins SPR:$a),
 | 
			
		||||
                 "fsqrts", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "fsqrts", " $dst, $a",
 | 
			
		||||
                 [(set SPR:$dst, (fsqrt SPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
//===----------------------------------------------------------------------===//
 | 
			
		||||
| 
						 | 
				
			
			@ -225,16 +225,16 @@ def FSQRTS  : ASuI<0b11101011, 0b0001, 0b1100, (outs SPR:$dst), (ins SPR:$a),
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
def FMRS   : AVConv2I<0b11100001, 0b1010, (outs GPR:$dst), (ins SPR:$src),
 | 
			
		||||
                 "fmrs", " $dst, $src",
 | 
			
		||||
                 IIC_fpALU, "fmrs", " $dst, $src",
 | 
			
		||||
                 [(set GPR:$dst, (bitconvert SPR:$src))]>;
 | 
			
		||||
 | 
			
		||||
def FMSR   : AVConv4I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src),
 | 
			
		||||
                 "fmsr", " $dst, $src",
 | 
			
		||||
                 IIC_fpALU, "fmsr", " $dst, $src",
 | 
			
		||||
                 [(set SPR:$dst, (bitconvert GPR:$src))]>;
 | 
			
		||||
 | 
			
		||||
def FMRRD  : AVConv3I<0b11000101, 0b1011,
 | 
			
		||||
                      (outs GPR:$dst1, GPR:$dst2), (ins DPR:$src),
 | 
			
		||||
                 "fmrrd", " $dst1, $dst2, $src",
 | 
			
		||||
                 IIC_fpALU, "fmrrd", " $dst1, $dst2, $src",
 | 
			
		||||
                 [/* FIXME: Can't write pattern for multiple result instr*/]>;
 | 
			
		||||
 | 
			
		||||
// FMDHR: GPR -> SPR
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +242,7 @@ def FMRRD  : AVConv3I<0b11000101, 0b1011,
 | 
			
		|||
 | 
			
		||||
def FMDRR : AVConv5I<0b11000100, 0b1011,
 | 
			
		||||
                     (outs DPR:$dst), (ins GPR:$src1, GPR:$src2),
 | 
			
		||||
                "fmdrr", " $dst, $src1, $src2",
 | 
			
		||||
                IIC_fpALU, "fmdrr", " $dst, $src1, $src2",
 | 
			
		||||
                [(set DPR:$dst, (arm_fmdrr GPR:$src1, GPR:$src2))]>;
 | 
			
		||||
 | 
			
		||||
// FMRDH: SPR -> GPR
 | 
			
		||||
| 
						 | 
				
			
			@ -258,23 +258,23 @@ def FMDRR : AVConv5I<0b11000100, 0b1011,
 | 
			
		|||
// Int to FP:
 | 
			
		||||
 | 
			
		||||
def FSITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
 | 
			
		||||
                 "fsitod", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "fsitod", " $dst, $a",
 | 
			
		||||
                 [(set DPR:$dst, (arm_sitof SPR:$a))]> {
 | 
			
		||||
  let Inst{7} = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FSITOS : AVConv1I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
 | 
			
		||||
                 "fsitos", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "fsitos", " $dst, $a",
 | 
			
		||||
                 [(set SPR:$dst, (arm_sitof SPR:$a))]> {
 | 
			
		||||
  let Inst{7} = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FUITOD : AVConv1I<0b11101011, 0b1000, 0b1011, (outs DPR:$dst), (ins SPR:$a),
 | 
			
		||||
                 "fuitod", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "fuitod", " $dst, $a",
 | 
			
		||||
                 [(set DPR:$dst, (arm_uitof SPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
def FUITOS : AVConv1I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
 | 
			
		||||
                 "fuitos", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "fuitos", " $dst, $a",
 | 
			
		||||
                 [(set SPR:$dst, (arm_uitof SPR:$a))]>;
 | 
			
		||||
 | 
			
		||||
// FP to Int:
 | 
			
		||||
| 
						 | 
				
			
			@ -282,28 +282,28 @@ def FUITOS : AVConv1I<0b11101011, 0b1000, 0b1010, (outs SPR:$dst), (ins SPR:$a),
 | 
			
		|||
 | 
			
		||||
def FTOSIZD : AVConv1I<0b11101011, 0b1101, 0b1011,
 | 
			
		||||
                       (outs SPR:$dst), (ins DPR:$a),
 | 
			
		||||
                 "ftosizd", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "ftosizd", " $dst, $a",
 | 
			
		||||
                 [(set SPR:$dst, (arm_ftosi DPR:$a))]> {
 | 
			
		||||
  let Inst{7} = 1; // Z bit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FTOSIZS : AVConv1I<0b11101011, 0b1101, 0b1010,
 | 
			
		||||
                       (outs SPR:$dst), (ins SPR:$a),
 | 
			
		||||
                 "ftosizs", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "ftosizs", " $dst, $a",
 | 
			
		||||
                 [(set SPR:$dst, (arm_ftosi SPR:$a))]> {
 | 
			
		||||
  let Inst{7} = 1; // Z bit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FTOUIZD : AVConv1I<0b11101011, 0b1100, 0b1011,
 | 
			
		||||
                       (outs SPR:$dst), (ins DPR:$a),
 | 
			
		||||
                 "ftouizd", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "ftouizd", " $dst, $a",
 | 
			
		||||
                 [(set SPR:$dst, (arm_ftoui DPR:$a))]> {
 | 
			
		||||
  let Inst{7} = 1; // Z bit
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FTOUIZS : AVConv1I<0b11101011, 0b1100, 0b1010,
 | 
			
		||||
                       (outs SPR:$dst), (ins SPR:$a),
 | 
			
		||||
                 "ftouizs", " $dst, $a",
 | 
			
		||||
                 IIC_fpALU, "ftouizs", " $dst, $a",
 | 
			
		||||
                 [(set SPR:$dst, (arm_ftoui SPR:$a))]> {
 | 
			
		||||
  let Inst{7} = 1; // Z bit
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -313,34 +313,34 @@ def FTOUIZS : AVConv1I<0b11101011, 0b1100, 0b1010,
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
def FMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
 | 
			
		||||
                "fmacd", " $dst, $a, $b",
 | 
			
		||||
                IIC_fpALU, "fmacd", " $dst, $a, $b",
 | 
			
		||||
                [(set DPR:$dst, (fadd (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
 | 
			
		||||
                RegConstraint<"$dstin = $dst">;
 | 
			
		||||
 | 
			
		||||
def FMACS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
 | 
			
		||||
                 "fmacs", " $dst, $a, $b",
 | 
			
		||||
                 IIC_fpALU, "fmacs", " $dst, $a, $b",
 | 
			
		||||
                 [(set SPR:$dst, (fadd (fmul SPR:$a, SPR:$b), SPR:$dstin))]>,
 | 
			
		||||
                 RegConstraint<"$dstin = $dst">;
 | 
			
		||||
 | 
			
		||||
def FMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
 | 
			
		||||
                "fmscd", " $dst, $a, $b",
 | 
			
		||||
                IIC_fpALU, "fmscd", " $dst, $a, $b",
 | 
			
		||||
                [(set DPR:$dst, (fsub (fmul DPR:$a, DPR:$b), DPR:$dstin))]>,
 | 
			
		||||
                RegConstraint<"$dstin = $dst">;
 | 
			
		||||
 | 
			
		||||
def FMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
 | 
			
		||||
                "fmscs", " $dst, $a, $b",
 | 
			
		||||
                IIC_fpALU, "fmscs", " $dst, $a, $b",
 | 
			
		||||
                [(set SPR:$dst, (fsub (fmul SPR:$a, SPR:$b), SPR:$dstin))]>,
 | 
			
		||||
                RegConstraint<"$dstin = $dst">;
 | 
			
		||||
 | 
			
		||||
def FNMACD : ADbI<0b11100000, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
 | 
			
		||||
                 "fnmacd", " $dst, $a, $b",
 | 
			
		||||
                 IIC_fpALU, "fnmacd", " $dst, $a, $b",
 | 
			
		||||
             [(set DPR:$dst, (fadd (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
 | 
			
		||||
                RegConstraint<"$dstin = $dst"> {
 | 
			
		||||
  let Inst{6} = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FNMACS : ASbIn<0b11100000, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
 | 
			
		||||
                  "fnmacs", " $dst, $a, $b",
 | 
			
		||||
                  IIC_fpALU, "fnmacs", " $dst, $a, $b",
 | 
			
		||||
             [(set SPR:$dst, (fadd (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
 | 
			
		||||
                RegConstraint<"$dstin = $dst"> {
 | 
			
		||||
  let Inst{6} = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -352,14 +352,14 @@ def : Pat<(fsub SPR:$dstin, (fmul SPR:$a, SPR:$b)),
 | 
			
		|||
          (FNMACS SPR:$dstin, SPR:$a, SPR:$b)>, Requires<[DontUseNEONForFP]>;
 | 
			
		||||
 | 
			
		||||
def FNMSCD : ADbI<0b11100001, (outs DPR:$dst), (ins DPR:$dstin, DPR:$a, DPR:$b),
 | 
			
		||||
                 "fnmscd", " $dst, $a, $b",
 | 
			
		||||
                 IIC_fpALU, "fnmscd", " $dst, $a, $b",
 | 
			
		||||
             [(set DPR:$dst, (fsub (fneg (fmul DPR:$a, DPR:$b)), DPR:$dstin))]>,
 | 
			
		||||
                RegConstraint<"$dstin = $dst"> {
 | 
			
		||||
  let Inst{6} = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
def FNMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
 | 
			
		||||
                "fnmscs", " $dst, $a, $b",
 | 
			
		||||
                IIC_fpALU, "fnmscs", " $dst, $a, $b",
 | 
			
		||||
             [(set SPR:$dst, (fsub (fneg (fmul SPR:$a, SPR:$b)), SPR:$dstin))]>,
 | 
			
		||||
                RegConstraint<"$dstin = $dst"> {
 | 
			
		||||
  let Inst{6} = 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -371,25 +371,25 @@ def FNMSCS : ASbI<0b11100001, (outs SPR:$dst), (ins SPR:$dstin, SPR:$a, SPR:$b),
 | 
			
		|||
 | 
			
		||||
def FCPYDcc  : ADuI<0b11101011, 0b0000, 0b0100,
 | 
			
		||||
                    (outs DPR:$dst), (ins DPR:$false, DPR:$true),
 | 
			
		||||
                    "fcpyd", " $dst, $true",
 | 
			
		||||
                    IIC_fpALU, "fcpyd", " $dst, $true",
 | 
			
		||||
                [/*(set DPR:$dst, (ARMcmov DPR:$false, DPR:$true, imm:$cc))*/]>,
 | 
			
		||||
                    RegConstraint<"$false = $dst">;
 | 
			
		||||
 | 
			
		||||
def FCPYScc  : ASuI<0b11101011, 0b0000, 0b0100,
 | 
			
		||||
                    (outs SPR:$dst), (ins SPR:$false, SPR:$true),
 | 
			
		||||
                    "fcpys", " $dst, $true",
 | 
			
		||||
                    IIC_fpALU, "fcpys", " $dst, $true",
 | 
			
		||||
                [/*(set SPR:$dst, (ARMcmov SPR:$false, SPR:$true, imm:$cc))*/]>,
 | 
			
		||||
                    RegConstraint<"$false = $dst">;
 | 
			
		||||
 | 
			
		||||
def FNEGDcc  : ADuI<0b11101011, 0b0001, 0b0100,
 | 
			
		||||
                    (outs DPR:$dst), (ins DPR:$false, DPR:$true),
 | 
			
		||||
                    "fnegd", " $dst, $true",
 | 
			
		||||
                    IIC_fpALU, "fnegd", " $dst, $true",
 | 
			
		||||
                [/*(set DPR:$dst, (ARMcneg DPR:$false, DPR:$true, imm:$cc))*/]>,
 | 
			
		||||
                    RegConstraint<"$false = $dst">;
 | 
			
		||||
 | 
			
		||||
def FNEGScc  : ASuI<0b11101011, 0b0001, 0b0100,
 | 
			
		||||
                    (outs SPR:$dst), (ins SPR:$false, SPR:$true),
 | 
			
		||||
                    "fnegs", " $dst, $true",
 | 
			
		||||
                    IIC_fpALU, "fnegs", " $dst, $true",
 | 
			
		||||
                [/*(set SPR:$dst, (ARMcneg SPR:$false, SPR:$true, imm:$cc))*/]>,
 | 
			
		||||
                    RegConstraint<"$false = $dst">;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -399,7 +399,7 @@ def FNEGScc  : ASuI<0b11101011, 0b0001, 0b0100,
 | 
			
		|||
//
 | 
			
		||||
 | 
			
		||||
let Defs = [CPSR], Uses = [FPSCR] in
 | 
			
		||||
def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, "fmstat", "", [(arm_fmstat)]> {
 | 
			
		||||
def FMSTAT : VFPAI<(outs), (ins), VFPMiscFrm, IIC_fpALU, "fmstat", "", [(arm_fmstat)]> {
 | 
			
		||||
  let Inst{27-20} = 0b11101111;
 | 
			
		||||
  let Inst{19-16} = 0b0001;
 | 
			
		||||
  let Inst{15-12} = 0b1111;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue