Newer
Older
let Inst{5-4} = 0b00;
}
def BT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
Evan Cheng
committed
!strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
[(set rGPR:$dst, (add rGPR:$acc, (opnode (sext_inreg rGPR:$a, i16),
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0110;
let Inst{22-20} = 0b001;
let Inst{15-12} = {?, ?, ?, ?}; // Ra
let Inst{7-6} = 0b00;
let Inst{5-4} = 0b01;
}
def TB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
Evan Cheng
committed
!strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
[(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0110;
let Inst{22-20} = 0b001;
let Inst{15-12} = {?, ?, ?, ?}; // Ra
let Inst{7-6} = 0b00;
let Inst{5-4} = 0b10;
}
def TT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
Evan Cheng
committed
!strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
[(set rGPR:$dst, (add rGPR:$acc, (opnode (sra rGPR:$a, (i32 16)),
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0110;
let Inst{22-20} = 0b001;
let Inst{15-12} = {?, ?, ?, ?}; // Ra
let Inst{7-6} = 0b00;
let Inst{5-4} = 0b11;
}
def WB : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
Evan Cheng
committed
!strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
[(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0110;
let Inst{22-20} = 0b011;
let Inst{15-12} = {?, ?, ?, ?}; // Ra
let Inst{7-6} = 0b00;
let Inst{5-4} = 0b00;
}
def WT : T2I<(outs rGPR:$dst), (ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC16,
Evan Cheng
committed
!strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
[(set rGPR:$dst, (add rGPR:$acc, (sra (opnode rGPR:$a,
let Inst{31-27} = 0b11111;
let Inst{26-23} = 0b0110;
let Inst{22-20} = 0b011;
let Inst{15-12} = {?, ?, ?, ?}; // Ra
let Inst{7-6} = 0b00;
let Inst{5-4} = 0b01;
}
}
defm t2SMUL : T2I_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
defm t2SMLA : T2I_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
// Halfword multiple accumulate long: SMLAL<x><y> -- for disassembly only
def t2SMLALBB : T2I_mac<1, 0b100, 0b1000, (outs rGPR:$ldst,rGPR:$hdst),
(ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>;
def t2SMLALBT : T2I_mac<1, 0b100, 0b1001, (outs rGPR:$ldst,rGPR:$hdst),
(ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>;
def t2SMLALTB : T2I_mac<1, 0b100, 0b1010, (outs rGPR:$ldst,rGPR:$hdst),
(ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>;
def t2SMLALTT : T2I_mac<1, 0b100, 0b1011, (outs rGPR:$ldst,rGPR:$hdst),
(ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>;
// Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
// These are for disassembly only.
def t2SMUAD: T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
IIC_iMAC32, "smuad", "\t$dst, $a, $b", []> {
let Inst{15-12} = 0b1111;
}
def t2SMUADX:T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
IIC_iMAC32, "smuadx", "\t$dst, $a, $b", []> {
let Inst{15-12} = 0b1111;
}
def t2SMUSD: T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
IIC_iMAC32, "smusd", "\t$dst, $a, $b", []> {
let Inst{15-12} = 0b1111;
}
def t2SMUSDX:T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst), (ins rGPR:$a, rGPR:$b),
IIC_iMAC32, "smusdx", "\t$dst, $a, $b", []> {
let Inst{15-12} = 0b1111;
}
def t2SMLAD : T2I_mac<0, 0b010, 0b0000, (outs rGPR:$dst),
(ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlad",
"\t$dst, $a, $b, $acc", []>;
def t2SMLADX : T2I_mac<0, 0b010, 0b0001, (outs rGPR:$dst),
(ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smladx",
"\t$dst, $a, $b, $acc", []>;
def t2SMLSD : T2I_mac<0, 0b100, 0b0000, (outs rGPR:$dst),
(ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsd",
"\t$dst, $a, $b, $acc", []>;
def t2SMLSDX : T2I_mac<0, 0b100, 0b0001, (outs rGPR:$dst),
(ins rGPR:$a, rGPR:$b, rGPR:$acc), IIC_iMAC32, "smlsdx",
"\t$dst, $a, $b, $acc", []>;
def t2SMLALD : T2I_mac<1, 0b100, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
(ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlald",
"\t$ldst, $hdst, $a, $b", []>;
def t2SMLALDX : T2I_mac<1, 0b100, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
(ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlaldx",
"\t$ldst, $hdst, $a, $b", []>;
def t2SMLSLD : T2I_mac<1, 0b101, 0b1100, (outs rGPR:$ldst,rGPR:$hdst),
(ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsld",
"\t$ldst, $hdst, $a, $b", []>;
def t2SMLSLDX : T2I_mac<1, 0b101, 0b1101, (outs rGPR:$ldst,rGPR:$hdst),
(ins rGPR:$a,rGPR:$b), IIC_iMAC64, "smlsldx",
"\t$ldst, $hdst, $a, $b", []>;
Evan Cheng
committed
//===----------------------------------------------------------------------===//
// Misc. Arithmetic Instructions.
//
class T2I_misc<bits<2> op1, bits<2> op2, dag oops, dag iops,
InstrItinClass itin, string opc, string asm, list<dag> pattern>
: T2I<oops, iops, itin, opc, asm, pattern> {
let Inst{31-27} = 0b11111;
let Inst{26-22} = 0b01010;
let Inst{21-20} = op1;
let Inst{15-12} = 0b1111;
let Inst{7-6} = 0b10;
let Inst{5-4} = op2;
}
def t2CLZ : T2I_misc<0b11, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
"clz", "\t$dst, $src", [(set rGPR:$dst, (ctlz rGPR:$src))]>;
Evan Cheng
committed
def t2RBIT : T2I_misc<0b01, 0b10, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
Evan Cheng
committed
"rbit", "\t$dst, $src",
[(set rGPR:$dst, (ARMrbit rGPR:$src))]>;
def t2REV : T2I_misc<0b01, 0b00, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
"rev", ".w\t$dst, $src", [(set rGPR:$dst, (bswap rGPR:$src))]>;
Evan Cheng
committed
def t2REV16 : T2I_misc<0b01, 0b01, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
"rev16", ".w\t$dst, $src",
[(set rGPR:$dst,
(or (and (srl rGPR:$src, (i32 8)), 0xFF),
(or (and (shl rGPR:$src, (i32 8)), 0xFF00),
(or (and (srl rGPR:$src, (i32 8)), 0xFF0000),
Evan Cheng
committed
def t2REVSH : T2I_misc<0b01, 0b11, (outs rGPR:$dst), (ins rGPR:$src), IIC_iUNAr,
"revsh", ".w\t$dst, $src",
[(set rGPR:$dst,
Evan Cheng
committed
(sext_inreg
(or (srl (and rGPR:$src, 0xFF00), (i32 8)),
(shl rGPR:$src, (i32 8))), i16))]>;
Evan Cheng
committed
def t2PKHBT : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
IIC_iBITsi, "pkhbt", "\t$dst, $src1, $src2$sh",
[(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF),
(and (shl rGPR:$src2, lsl_amt:$sh),
0xFFFF0000)))]>,
Requires<[HasT2ExtractPack, IsThumb2]> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
let Inst{24-20} = 0b01100;
let Inst{5} = 0; // BT form
let Inst{4} = 0;
}
// Alternate cases for PKHBT where identities eliminate some nodes.
def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (and rGPR:$src2, 0xFFFF0000)),
(t2PKHBT rGPR:$src1, rGPR:$src2, 0)>,
Requires<[HasT2ExtractPack, IsThumb2]>;
def : T2Pat<(or (and rGPR:$src1, 0xFFFF), (shl rGPR:$src2, imm16_31:$sh)),
(t2PKHBT rGPR:$src1, rGPR:$src2, (lsl_shift_imm imm16_31:$sh))>,
Requires<[HasT2ExtractPack, IsThumb2]>;
// Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
// will match the pattern below.
def t2PKHTB : T2I<(outs rGPR:$dst), (ins rGPR:$src1, rGPR:$src2, shift_imm:$sh),
IIC_iBITsi, "pkhtb", "\t$dst, $src1, $src2$sh",
[(set rGPR:$dst, (or (and rGPR:$src1, 0xFFFF0000),
(and (sra rGPR:$src2, asr_amt:$sh),
0xFFFF)))]>,
Requires<[HasT2ExtractPack, IsThumb2]> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
let Inst{24-20} = 0b01100;
let Inst{5} = 1; // TB form
let Inst{4} = 0;
}
// Alternate cases for PKHTB where identities eliminate some nodes. Note that
// a shift amount of 0 is *not legal* here, it is PKHBT instead.
def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000), (srl rGPR:$src2, imm16_31:$sh)),
(t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm16_31:$sh))>,
Requires<[HasT2ExtractPack, IsThumb2]>;
def : T2Pat<(or (and rGPR:$src1, 0xFFFF0000),
(and (srl rGPR:$src2, imm1_15:$sh), 0xFFFF)),
(t2PKHTB rGPR:$src1, rGPR:$src2, (asr_shift_imm imm1_15:$sh))>,
Requires<[HasT2ExtractPack, IsThumb2]>;
Evan Cheng
committed
//===----------------------------------------------------------------------===//
// Comparison Instructions...
//
defm t2CMP : T2I_cmp_irs<0b1101, "cmp",
IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
defm t2CMPz : T2I_cmp_irs<0b1101, "cmp",
IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
Evan Cheng
committed
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
// Compare-to-zero still works out, just not the relationals
//defm t2CMN : T2I_cmp_irs<0b1000, "cmn",
// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
defm t2CMNz : T2I_cmp_irs<0b1000, "cmn",
IIC_iCMPi, IIC_iCMPr, IIC_iCMPsi,
BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
//def : T2Pat<(ARMcmp GPR:$src, t2_so_imm_neg:$imm),
// (t2CMNri GPR:$src, t2_so_imm_neg:$imm)>;
def : T2Pat<(ARMcmpZ GPR:$src, t2_so_imm_neg:$imm),
(t2CMNzri GPR:$src, t2_so_imm_neg:$imm)>;
Evan Cheng
committed
defm t2TST : T2I_cmp_irs<0b0000, "tst",
IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>>;
defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
IIC_iTSTi, IIC_iTSTr, IIC_iTSTsi,
BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>>;
Evan Cheng
committed
// 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. :(
let neverHasSideEffects = 1 in {
let isAsCheapAsAMove = 1 in
def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr,
Evan Cheng
committed
"mov", ".w\t$dst, $true",
[/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>,
RegConstraint<"$false = $dst"> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
let Inst{24-21} = 0b0010;
let Inst{20} = 0; // The S bit.
let Inst{19-16} = 0b1111; // Rn
let Inst{14-12} = 0b000;
let Inst{7-4} = 0b0000;
}
def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
Evan Cheng
committed
IIC_iCMOVi, "mov", ".w\t$dst, $true",
[/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
RegConstraint<"$false = $dst"> {
let Inst{31-27} = 0b11110;
let Inst{25} = 0;
let Inst{24-21} = 0b0010;
let Inst{20} = 0; // The S bit.
let Inst{19-16} = 0b1111; // Rn
let Inst{15} = 0;
}
def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
"movw", "\t$dst, $src", []>,
RegConstraint<"$false = $dst"> {
let Inst{31-27} = 0b11110;
let Inst{25} = 1;
let Inst{24-21} = 0b0010;
let Inst{20} = 0; // The S bit.
let Inst{15} = 0;
}
def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
(ins rGPR:$false, i32imm:$src, pred:$p),
IIC_iMOVix2, "", []>, RegConstraint<"$false = $dst">;
let isAsCheapAsAMove = 1 in
def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
IIC_iCMOVi, "mvn", ".w\t$dst, $true",
[/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true,
imm:$cc, CCR:$ccr))*/]>,
RegConstraint<"$false = $dst"> {
let Inst{31-27} = 0b11110;
let Inst{25} = 0;
let Inst{24-21} = 0b0011;
let Inst{20} = 0; // The S bit.
let Inst{19-16} = 0b1111; // Rn
let Inst{15} = 0;
}
class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
string opc, string asm, list<dag> pattern>
: T2I<oops, iops, itin, opc, asm, pattern> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b01;
let Inst{24-21} = 0b0010;
let Inst{20} = 0; // The S bit.
let Inst{19-16} = 0b1111; // Rn
let Inst{5-4} = opcod; // Shift type.
}
def t2MOVCClsl : T2I_movcc_sh<0b00, (outs rGPR:$dst),
(ins rGPR:$false, rGPR:$true, i32imm:$rhs),
IIC_iCMOVsi, "lsl", ".w\t$dst, $true, $rhs", []>,
RegConstraint<"$false = $dst">;
def t2MOVCClsr : T2I_movcc_sh<0b01, (outs rGPR:$dst),
(ins rGPR:$false, rGPR:$true, i32imm:$rhs),
IIC_iCMOVsi, "lsr", ".w\t$dst, $true, $rhs", []>,
RegConstraint<"$false = $dst">;
def t2MOVCCasr : T2I_movcc_sh<0b10, (outs rGPR:$dst),
(ins rGPR:$false, rGPR:$true, i32imm:$rhs),
IIC_iCMOVsi, "asr", ".w\t$dst, $true, $rhs", []>,
RegConstraint<"$false = $dst">;
def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$dst),
(ins rGPR:$false, rGPR:$true, i32imm:$rhs),
IIC_iCMOVsi, "ror", ".w\t$dst, $true, $rhs", []>,
RegConstraint<"$false = $dst">;
Owen Anderson
committed
} // neverHasSideEffects
Evan Cheng
committed
//===----------------------------------------------------------------------===//
// Atomic operations intrinsics
//
// memory barriers protect the atomic sequences
let hasSideEffects = 1 in {
def t2DMB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
"dmb", "\t$opt", [(ARMMemBarrier (i32 imm:$opt))]>,
Requires<[IsThumb, HasDB]> {
bits<4> opt;
let Inst{31-4} = 0xf3bf8f5;
let Inst{3-0} = opt;
}
}
def t2DSB : AInoP<(outs), (ins memb_opt:$opt), ThumbFrm, NoItinerary,
"dsb", "\t$opt",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsThumb, HasDB]> {
bits<4> opt;
let Inst{31-4} = 0xf3bf8f4;
let Inst{3-0} = opt;
Johnny Chen
committed
}
// ISB has only full system option -- for disassembly only
def t2ISB : T2I<(outs), (ins), NoItinerary, "isb", "",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsThumb2, HasV7]> {
let Inst{31-4} = 0xf3bf8f6;
Johnny Chen
committed
let Inst{3-0} = 0b1111;
}
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
class T2I_ldrex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
InstrItinClass itin, string opc, string asm, string cstr,
list<dag> pattern, bits<4> rt2 = 0b1111>
: Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001101;
let Inst{11-8} = rt2;
let Inst{7-6} = 0b01;
let Inst{5-4} = opcod;
let Inst{3-0} = 0b1111;
}
class T2I_strex<bits<2> opcod, dag oops, dag iops, AddrMode am, SizeFlagVal sz,
InstrItinClass itin, string opc, string asm, string cstr,
list<dag> pattern, bits<4> rt2 = 0b1111>
: Thumb2I<oops, iops, am, sz, itin, opc, asm, cstr, pattern> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001100;
let Inst{11-8} = rt2;
let Inst{7-6} = 0b01;
let Inst{5-4} = opcod;
}
let mayLoad = 1 in {
def t2LDREXB : T2I_ldrex<0b00, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
Size4Bytes, NoItinerary, "ldrexb", "\t$dest, [$ptr]",
"", []>;
def t2LDREXH : T2I_ldrex<0b01, (outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
Size4Bytes, NoItinerary, "ldrexh", "\t$dest, [$ptr]",
"", []>;
def t2LDREX : Thumb2I<(outs rGPR:$dest), (ins rGPR:$ptr), AddrModeNone,
Size4Bytes, NoItinerary,
"ldrex", "\t$dest, [$ptr]", "",
[]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000101;
let Inst{11-8} = 0b1111;
let Inst{7-0} = 0b00000000; // imm8 = 0
}
def t2LDREXD : T2I_ldrex<0b11, (outs rGPR:$dest, rGPR:$dest2), (ins rGPR:$ptr),
AddrModeNone, Size4Bytes, NoItinerary,
"ldrexd", "\t$dest, $dest2, [$ptr]", "",
[], {?, ?, ?, ?}>;
let mayStore = 1, Constraints = "@earlyclobber $success" in {
def t2STREXB : T2I_strex<0b00, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
AddrModeNone, Size4Bytes, NoItinerary,
"strexb", "\t$success, $src, [$ptr]", "", []>;
def t2STREXH : T2I_strex<0b01, (outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
AddrModeNone, Size4Bytes, NoItinerary,
"strexh", "\t$success, $src, [$ptr]", "", []>;
def t2STREX : Thumb2I<(outs rGPR:$success), (ins rGPR:$src, rGPR:$ptr),
AddrModeNone, Size4Bytes, NoItinerary,
"strex", "\t$success, $src, [$ptr]", "",
[]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000100;
let Inst{7-0} = 0b00000000; // imm8 = 0
}
def t2STREXD : T2I_strex<0b11, (outs rGPR:$success),
(ins rGPR:$src, rGPR:$src2, rGPR:$ptr),
AddrModeNone, Size4Bytes, NoItinerary,
"strexd", "\t$success, $src, $src2, [$ptr]", "", [],
{?, ?, ?, ?}>;
// Clear-Exclusive is for disassembly only.
def t2CLREX : T2I<(outs), (ins), NoItinerary, "clrex", "",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV7]> {
let Inst{31-20} = 0xf3b;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
let Inst{7-4} = 0b0010;
}
David Goodwin
committed
//===----------------------------------------------------------------------===//
// TLS Instructions
//
// __aeabi_read_tp preserves the registers r1-r3.
let isCall = 1,
Defs = [R0, R12, LR, CPSR] in {
David Goodwin
committed
def t2TPsoft : T2XI<(outs), (ins), IIC_Br,
Evan Cheng
committed
"bl\t__aeabi_read_tp",
[(set R0, ARMthread_pointer)]> {
let Inst{31-27} = 0b11110;
let Inst{15-14} = 0b11;
let Inst{12} = 1;
}
David Goodwin
committed
}
//===----------------------------------------------------------------------===//
// SJLJ Exception handling intrinsics
// eh_sjlj_setjmp() is an instruction sequence to store the return
// address and save #0 in R0 for the non-longjmp case.
// Since by its nature we may be coming from some other function to get
// here, and we're using the stack frame for the containing function to
// save/restore registers, we can't keep anything live in regs across
// the eh_sjlj_setjmp(), else it will almost certainly have been tromped upon
// when we get here from a longjmp(). We force everthing out of registers
// except for our own input by listing the relevant registers in Defs. By
// doing so, we also cause the prologue/epilogue code to actively preserve
// all of the callee-saved resgisters, which is exactly what we want.
// $val is a scratch register for our use.
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR, D0,
D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15,
D16, D17, D18, D19, D20, D21, D22, D23, D24, D25, D26, D27, D28, D29, D30,
D31 ], hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
def t2Int_eh_sjlj_setjmp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
AddrModeNone, SizeSpecial, NoItinerary, "", "",
[(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
Requires<[IsThumb2, HasVFP2]>;
let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, LR ],
hasSideEffects = 1, isBarrier = 1, isCodeGenOnly = 1 in {
def t2Int_eh_sjlj_setjmp_nofp : Thumb2XI<(outs), (ins tGPR:$src, tGPR:$val),
AddrModeNone, SizeSpecial, NoItinerary, "", "",
[(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>,
Requires<[IsThumb2, NoVFP]>;
}
//===----------------------------------------------------------------------===//
// Control-Flow Instructions
//
// FIXME: remove when we have a way to marking a MI with these properties.
// FIXME: $dst1 should be a def. But the extra ops must be in the end of the
// operand list.
// FIXME: Should pc be an implicit operand like PICADD, etc?
Evan Cheng
committed
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1, isCodeGenOnly = 1 in
def t2LDM_RET: T2XIt<(outs GPR:$wb), (ins GPR:$Rn, ldstm_mode:$amode, pred:$p,
reglist:$dsts, variable_ops),
IIC_iLoad_mBr,
"ldm${amode}${p}.w\t$Rn!, $dsts",
"$Rn = $wb", []> {
let Inst{31-27} = 0b11101;
let Inst{26-25} = 0b00;
let Inst{24-23} = {?, ?}; // IA: '01', DB: '10'
let Inst{22} = 0;
let Inst{21} = 1; // The W bit.
let Inst{20} = 1; // Load
}
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
let isPredicable = 1 in
David Goodwin
committed
def t2B : T2XI<(outs), (ins brtarget:$target), IIC_Br,
Evan Cheng
committed
"b.w\t$target",
[(br bb:$target)]> {
let Inst{31-27} = 0b11110;
let Inst{15-14} = 0b10;
let Inst{12} = 1;
}
let isNotDuplicable = 1, isIndirectBranch = 1,
isCodeGenOnly = 1 in { // $id doesn't exist in asmstring, should be lowered.
def t2BR_JT :
Evan Cheng
committed
T2JTI<(outs),
(ins GPR:$target, GPR:$index, jt2block_operand:$jt, i32imm:$id),
IIC_Br, "mov\tpc, $target$jt",
[(ARMbr2jt GPR:$target, GPR:$index, tjumptable:$jt, imm:$id)]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0100100;
let Inst{19-16} = 0b1111;
let Inst{14-12} = 0b000;
let Inst{11-8} = 0b1111; // Rd = pc
let Inst{7-4} = 0b0000;
}
Evan Cheng
committed
// FIXME: Add a non-pc based case that can be predicated.
let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
Evan Cheng
committed
def t2TBB :
Evan Cheng
committed
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
IIC_Br, "tbb\t$index$jt", []> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001101;
let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
let Inst{15-8} = 0b11110000;
let Inst{7-4} = 0b0000; // B form
}
Evan Cheng
committed
let isCodeGenOnly = 1 in // $id doesn't exist in asm string, should be lowered.
Evan Cheng
committed
def t2TBH :
Evan Cheng
committed
(ins tb_addrmode:$index, jt2block_operand:$jt, i32imm:$id),
IIC_Br, "tbh\t$index$jt", []> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001101;
let Inst{19-16} = 0b1111; // Rn = pc (table follows this instruction)
let Inst{15-8} = 0b11110000;
let Inst{7-4} = 0b0001; // H form
}
Johnny Chen
committed
// Generic versions of the above two instructions, for disassembly only
def t2TBBgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
"tbb", "\t[$a, $b]", []>{
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001101;
let Inst{15-8} = 0b11110000;
let Inst{7-4} = 0b0000; // B form
}
def t2TBHgen : T2I<(outs), (ins GPR:$a, GPR:$b), IIC_Br,
"tbh", "\t[$a, $b, lsl #1]", []> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0001101;
let Inst{15-8} = 0b11110000;
let Inst{7-4} = 0b0001; // H form
}
Evan Cheng
committed
} // isNotDuplicable, isIndirectBranch
} // isBranch, isTerminator, isBarrier
// 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
David Goodwin
committed
def t2Bcc : T2I<(outs), (ins brtarget:$target), IIC_Br,
Evan Cheng
committed
"b", ".w\t$target",
[/*(ARMbrcond bb:$target, imm:$cc)*/]> {
let Inst{31-27} = 0b11110;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
Evan Cheng
committed
let Defs = [ITSTATE] in
def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
AddrModeNone, Size2Bytes, IIC_iALUx,
"it$mask\t$cc", "", []> {
// 16-bit instruction.
Johnny Chen
committed
let Inst{31-16} = 0x0000;
let Inst{15-8} = 0b10111111;
}
// Branch and Exchange Jazelle -- for disassembly only
// Rm = Inst{19-16}
def t2BXJ : T2I<(outs), (ins rGPR:$func), NoItinerary, "bxj", "\t$func",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-20} = 0b111100;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
Johnny Chen
committed
// Change Processor State is a system instruction -- for disassembly only.
// The singleton $opt operand contains the following information:
// opt{4-0} = mode from Inst{4-0}
// opt{5} = changemode from Inst{17}
// opt{8-6} = AIF from Inst{8-6}
// opt{10-9} = imod from Inst{19-18} with 0b10 as enable and 0b11 as disable
Johnny Chen
committed
def t2CPS : T2XI<(outs),(ins cps_opt:$opt), NoItinerary, "cps$opt",
Johnny Chen
committed
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-20} = 0b111010;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
Johnny Chen
committed
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
// A6.3.4 Branches and miscellaneous control
// Table A6-14 Change Processor State, and hint instructions
// Helper class for disassembly only.
class T2I_hint<bits<8> op7_0, string opc, string asm>
: T2I<(outs), (ins), NoItinerary, opc, asm,
[/* For disassembly only; pattern left blank */]> {
let Inst{31-20} = 0xf3a;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
let Inst{10-8} = 0b000;
let Inst{7-0} = op7_0;
}
def t2NOP : T2I_hint<0b00000000, "nop", ".w">;
def t2YIELD : T2I_hint<0b00000001, "yield", ".w">;
def t2WFE : T2I_hint<0b00000010, "wfe", ".w">;
def t2WFI : T2I_hint<0b00000011, "wfi", ".w">;
def t2SEV : T2I_hint<0b00000100, "sev", ".w">;
def t2DBG : T2I<(outs),(ins i32imm:$opt), NoItinerary, "dbg", "\t$opt",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-20} = 0xf3a;
let Inst{15-14} = 0b10;
let Inst{12} = 0;
let Inst{10-8} = 0b000;
let Inst{7-4} = 0b1111;
}
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
// Secure Monitor Call is a system instruction -- for disassembly only
// Option = Inst{19-16}
def t2SMC : T2I<(outs), (ins i32imm:$opt), NoItinerary, "smc", "\t$opt",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26-20} = 0b1111111;
let Inst{15-12} = 0b1000;
}
// Store Return State is a system instruction -- for disassembly only
def t2SRSDBW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp!, $mode",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000010; // W = 1
}
def t2SRSDB : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsdb","\tsp, $mode",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000000; // W = 0
}
def t2SRSIAW : T2I<(outs),(ins i32imm:$mode),NoItinerary,"srsia","\tsp!, $mode",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0011010; // W = 1
}
def t2SRSIA : T2I<(outs), (ins i32imm:$mode),NoItinerary,"srsia","\tsp, $mode",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0011000; // W = 0
}
// Return From Exception is a system instruction -- for disassembly only
def t2RFEDBW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfedb", "\t$base!",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000011; // W = 1
}
def t2RFEDB : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeab", "\t$base",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0000001; // W = 0
}
def t2RFEIAW : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base!",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0011011; // W = 1
}
def t2RFEIA : T2I<(outs), (ins rGPR:$base), NoItinerary, "rfeia", "\t$base",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11101;
let Inst{26-20} = 0b0011001; // W = 0
}
Evan Cheng
committed
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
//
Jim Grosbach
committed
// Two piece so_imms.
def : T2Pat<(or rGPR:$LHS, t2_so_imm2part:$RHS),
(t2ORRri (t2ORRri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
Jim Grosbach
committed
(t2_so_imm2part_2 imm:$RHS))>;
def : T2Pat<(xor rGPR:$LHS, t2_so_imm2part:$RHS),
(t2EORri (t2EORri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
Jim Grosbach
committed
(t2_so_imm2part_2 imm:$RHS))>;
def : T2Pat<(add rGPR:$LHS, t2_so_imm2part:$RHS),
(t2ADDri (t2ADDri rGPR:$LHS, (t2_so_imm2part_1 imm:$RHS)),
Jim Grosbach
committed
(t2_so_imm2part_2 imm:$RHS))>;
def : T2Pat<(add rGPR:$LHS, t2_so_neg_imm2part:$RHS),
(t2SUBri (t2SUBri rGPR:$LHS, (t2_so_neg_imm2part_1 imm:$RHS)),
Jim Grosbach
committed
(t2_so_neg_imm2part_2 imm:$RHS))>;
Jim Grosbach
committed
Evan Cheng
committed
// 32-bit immediate using movw + movt.
// This is a single pseudo instruction to make it re-materializable.
// FIXME: Remove this when we can do generalized remat.
Evan Cheng
committed
let isReMaterializable = 1 in
def t2MOVi32imm : PseudoInst<(outs rGPR:$dst), (ins i32imm:$src), IIC_iMOVix2,
"", [(set rGPR:$dst, (i32 imm:$src))]>,
Requires<[IsThumb, HasV6T2]>;
Evan Cheng
committed
// ConstantPool, GlobalAddress, and JumpTable
def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>,
Requires<[IsThumb2, DontUseMovt]>;
def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2MOVi32imm tglobaladdr :$dst)>,
Requires<[IsThumb2, UseMovt]>;
def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
(t2LEApcrelJT tjumptable:$dst, imm:$id)>;
Evan Cheng
committed
// Pseudo instruction that combines ldr from constpool and add pc. This should
// be expanded into two instructions late to allow if-conversion and
// scheduling.
let canFoldAsLoad = 1, isReMaterializable = 1 in
Evan Cheng
committed
def t2LDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
Evan Cheng
committed
[(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
imm:$cp))]>,
Requires<[IsThumb2]>;
//===----------------------------------------------------------------------===//
// Move between special register and ARM core register -- for disassembly only
//
// Rd = Instr{11-8}
def t2MRS : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, cpsr",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-21} = 0b11111;
let Inst{20} = 0; // The R bit.
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
// Rd = Instr{11-8}
def t2MRSsys : T2I<(outs rGPR:$dst), (ins), NoItinerary, "mrs", "\t$dst, spsr",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-21} = 0b11111;
let Inst{20} = 1; // The R bit.
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
// Rn = Inst{19-16}
def t2MSR : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
Johnny Chen
committed
"\tcpsr$mask, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-21} = 0b11100;
let Inst{20} = 0; // The R bit.
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}
// Rn = Inst{19-16}
def t2MSRsys : T2I<(outs), (ins rGPR:$src, msr_mask:$mask), NoItinerary, "msr",
Johnny Chen
committed
"\tspsr$mask, $src",
[/* For disassembly only; pattern left blank */]> {
let Inst{31-27} = 0b11110;
let Inst{26} = 0;
let Inst{25-21} = 0b11100;
let Inst{20} = 1; // The R bit.
let Inst{15-14} = 0b10;
let Inst{12} = 0;
}