Newer
Older
let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
mayHaveSideEffects = 1 in
def LDRcp : AI2ldw<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm, IIC_iLoadr,
Evan Cheng
committed
"ldr", "\t$dst, $addr", []>;
def LDRH : AI3ldh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
IIC_iLoadr, "ldrh", "\t$dst, $addr",
[(set GPR:$dst, (zextloadi16 addrmode3:$addr))]>;
def LDRB : AI2ldb<(outs GPR:$dst), (ins addrmode2:$addr), LdFrm,
IIC_iLoadr, "ldrb", "\t$dst, $addr",
[(set GPR:$dst, (zextloadi8 addrmode2:$addr))]>;
def LDRSH : AI3ldsh<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
IIC_iLoadr, "ldrsh", "\t$dst, $addr",
[(set GPR:$dst, (sextloadi16 addrmode3:$addr))]>;
def LDRSB : AI3ldsb<(outs GPR:$dst), (ins addrmode3:$addr), LdMiscFrm,
IIC_iLoadr, "ldrsb", "\t$dst, $addr",
[(set GPR:$dst, (sextloadi8 addrmode3:$addr))]>;
Evan Cheng
committed
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in {
def LDRD : AI3ldd<(outs GPR:$dst1, GPR:$dst2), (ins addrmode3:$addr), LdMiscFrm,
IIC_iLoadr, "ldrd", "\t$dst1, $addr",
[]>, Requires<[IsARM, HasV5TE]>;
Evan Cheng
committed
def LDR_PRE : AI2ldwpr<(outs GPR:$dst, GPR:$base_wb),
(ins addrmode2:$addr), LdFrm, IIC_iLoadru,
Evan Cheng
committed
"ldr", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
Evan Cheng
committed
def LDR_POST : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
Evan Cheng
committed
"ldr", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
Evan Cheng
committed
def LDRH_PRE : AI3ldhpr<(outs GPR:$dst, GPR:$base_wb),
(ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
"ldrh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
Evan Cheng
committed
def LDRH_POST : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
"ldrh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
Evan Cheng
committed
def LDRB_PRE : AI2ldbpr<(outs GPR:$dst, GPR:$base_wb),
(ins addrmode2:$addr), LdFrm, IIC_iLoadru,
"ldrb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
Evan Cheng
committed
def LDRB_POST : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
"ldrb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
Evan Cheng
committed
def LDRSH_PRE : AI3ldshpr<(outs GPR:$dst, GPR:$base_wb),
(ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
"ldrsh", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
Evan Cheng
committed
def LDRSH_POST: AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
"ldrsh", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
Evan Cheng
committed
def LDRSB_PRE : AI3ldsbpr<(outs GPR:$dst, GPR:$base_wb),
(ins addrmode3:$addr), LdMiscFrm, IIC_iLoadru,
"ldrsb", "\t$dst, $addr!", "$addr.base = $base_wb", []>;
Evan Cheng
committed
def LDRSB_POST: AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
"ldrsb", "\t$dst, [$base], $offset", "$base = $base_wb", []>;
// LDRT, LDRBT, LDRSBT, LDRHT, LDRSHT are for disassembly only.
def LDRT : AI2ldwpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base, am2offset:$offset), LdFrm, IIC_iLoadru,
"ldrt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
let Inst{21} = 1; // overwrite
}
def LDRBT : AI2ldbpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base,am2offset:$offset), LdFrm, IIC_iLoadru,
"ldrbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
let Inst{21} = 1; // overwrite
}
def LDRSBT : AI3ldsbpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base,am2offset:$offset), LdMiscFrm, IIC_iLoadru,
"ldrsbt", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
let Inst{21} = 1; // overwrite
}
def LDRHT : AI3ldhpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base, am3offset:$offset), LdMiscFrm, IIC_iLoadru,
"ldrht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
let Inst{21} = 1; // overwrite
}
def LDRSHT : AI3ldshpo<(outs GPR:$dst, GPR:$base_wb),
(ins GPR:$base,am3offset:$offset), LdMiscFrm, IIC_iLoadru,
"ldrsht", "\t$dst, [$base], $offset", "$base = $base_wb", []> {
let Inst{21} = 1; // overwrite
}
def STR : AI2stw<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
Evan Cheng
committed
"str", "\t$src, $addr",
[(store GPR:$src, addrmode2:$addr)]>;
// Stores with truncate
def STRH : AI3sth<(outs), (ins GPR:$src, addrmode3:$addr), StMiscFrm,
IIC_iStorer, "strh", "\t$src, $addr",
[(truncstorei16 GPR:$src, addrmode3:$addr)]>;
def STRB : AI2stb<(outs), (ins GPR:$src, addrmode2:$addr), StFrm, IIC_iStorer,
"strb", "\t$src, $addr",
[(truncstorei8 GPR:$src, addrmode2:$addr)]>;
// Store doubleword
Evan Cheng
committed
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
David Goodwin
committed
def STRD : AI3std<(outs), (ins GPR:$src1, GPR:$src2, addrmode3:$addr),
StMiscFrm, IIC_iStorer,
"strd", "\t$src1, $addr", []>, Requires<[IsARM, HasV5TE]>;
Evan Cheng
committed
def STR_PRE : AI2stwpr<(outs GPR:$base_wb),
(ins GPR:$src, GPR:$base, am2offset:$offset),
StFrm, IIC_iStoreru,
Evan Cheng
committed
"str", "\t$src, [$base, $offset]!", "$base = $base_wb",
[(set GPR:$base_wb,
(pre_store GPR:$src, GPR:$base, am2offset:$offset))]>;
Evan Cheng
committed
def STR_POST : AI2stwpo<(outs GPR:$base_wb),
StFrm, IIC_iStoreru,
Evan Cheng
committed
"str", "\t$src, [$base], $offset", "$base = $base_wb",
[(set GPR:$base_wb,
(post_store GPR:$src, GPR:$base, am2offset:$offset))]>;
Evan Cheng
committed
def STRH_PRE : AI3sthpr<(outs GPR:$base_wb),
StMiscFrm, IIC_iStoreru,
"strh", "\t$src, [$base, $offset]!", "$base = $base_wb",
[(set GPR:$base_wb,
(pre_truncsti16 GPR:$src, GPR:$base,am3offset:$offset))]>;
Evan Cheng
committed
def STRH_POST: AI3sthpo<(outs GPR:$base_wb),
StMiscFrm, IIC_iStoreru,
"strh", "\t$src, [$base], $offset", "$base = $base_wb",
[(set GPR:$base_wb, (post_truncsti16 GPR:$src,
GPR:$base, am3offset:$offset))]>;
Evan Cheng
committed
def STRB_PRE : AI2stbpr<(outs GPR:$base_wb),
StFrm, IIC_iStoreru,
"strb", "\t$src, [$base, $offset]!", "$base = $base_wb",
[(set GPR:$base_wb, (pre_truncsti8 GPR:$src,
GPR:$base, am2offset:$offset))]>;
Evan Cheng
committed
def STRB_POST: AI2stbpo<(outs GPR:$base_wb),
StFrm, IIC_iStoreru,
"strb", "\t$src, [$base], $offset", "$base = $base_wb",
[(set GPR:$base_wb, (post_truncsti8 GPR:$src,
GPR:$base, am2offset:$offset))]>;
// STRT and STRBT are for disassembly only.
def STRT : AI2stwpo<(outs GPR:$base_wb),
StFrm, IIC_iStoreru,
"strt", "\t$src, [$base], $offset", "$base = $base_wb",
[/* For disassembly only; pattern left blank */]> {
let Inst{21} = 1; // overwrite
}
def STRBT : AI2stbpo<(outs GPR:$base_wb),
StFrm, IIC_iStoreru,
"strbt", "\t$src, [$base], $offset", "$base = $base_wb",
[/* For disassembly only; pattern left blank */]> {
let Inst{21} = 1; // overwrite
}
//===----------------------------------------------------------------------===//
// Load / store multiple Instructions.
//
Evan Cheng
committed
let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
Evan Cheng
committed
def LDM : AXI4ld<(outs),
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
LdStMulFrm, IIC_iLoadm, "ldm${addr:submode}${p}\t$addr, $wb",
[]>;
Evan Cheng
committed
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
Evan Cheng
committed
def STM : AXI4st<(outs),
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
LdStMulFrm, IIC_iStorem, "stm${addr:submode}${p}\t$addr, $wb",
[]>;
//===----------------------------------------------------------------------===//
// Move Instructions.
//
let neverHasSideEffects = 1 in
def MOVr : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
Evan Cheng
committed
"mov", "\t$dst, $src", []>, UnaryDP {
Johnny Chen
committed
let Inst{11-4} = 0b00000000;
let Inst{25} = 0;
}
def MOVs : AsI1<0b1101, (outs GPR:$dst), (ins so_reg:$src),
DPSoRegFrm, IIC_iMOVsr,
Evan Cheng
committed
"mov", "\t$dst, $src", [(set GPR:$dst, so_reg:$src)]>, UnaryDP {
let Inst{25} = 0;
}
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
def MOVi : AsI1<0b1101, (outs GPR:$dst), (ins so_imm:$src), DPFrm, IIC_iMOVi,
Evan Cheng
committed
"mov", "\t$dst, $src", [(set GPR:$dst, so_imm:$src)]>, UnaryDP {
let Inst{25} = 1;
}
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
def MOVi16 : AI1<0b1000, (outs GPR:$dst), (ins i32imm:$src),
DPFrm, IIC_iMOVi,
Evan Cheng
committed
"movw", "\t$dst, $src",
[(set GPR:$dst, imm0_65535:$src)]>,
Johnny Chen
committed
Requires<[IsARM, HasV6T2]>, UnaryDP {
let Inst{25} = 1;
}
Evan Cheng
committed
let Constraints = "$src = $dst" in
def MOVTi16 : AI1<0b1010, (outs GPR:$dst), (ins GPR:$src, i32imm:$imm),
DPFrm, IIC_iMOVi,
"movt", "\t$dst, $imm",
[(set GPR:$dst,
lo16AllZero:$imm))]>, UnaryDP,
Requires<[IsARM, HasV6T2]> {
let Inst{25} = 1;
Evan Cheng
committed
}
Evan Cheng
committed
def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>,
Requires<[IsARM, HasV6T2]>;
def MOVrx : AsI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, IIC_iMOVsi,
Evan Cheng
committed
"mov", "\t$dst, $src, rrx",
Evan Cheng
committed
[(set GPR:$dst, (ARMrrx GPR:$src))]>, UnaryDP;
// These aren't really mov instructions, but we have to define them this way
// due to flag operands.
Evan Cheng
committed
let Defs = [CPSR] in {
def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1",
Evan Cheng
committed
[(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP;
def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo,
IIC_iMOVsi, "movs", "\t$dst, $src, asr #1",
Evan Cheng
committed
[(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP;
Evan Cheng
committed
}
//===----------------------------------------------------------------------===//
// Extend Instructions.
//
defm SXTB : AI_unary_rrot<0b01101010,
"sxtb", UnOpFrag<(sext_inreg node:$Src, i8)>>;
defm SXTH : AI_unary_rrot<0b01101011,
"sxth", UnOpFrag<(sext_inreg node:$Src, i16)>>;
defm SXTAB : AI_bin_rrot<0b01101010,
"sxtab", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
defm SXTAH : AI_bin_rrot<0b01101011,
"sxtah", BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
defm UXTB : AI_unary_rrot<0b01101110,
"uxtb" , UnOpFrag<(and node:$Src, 0x000000FF)>>;
defm UXTH : AI_unary_rrot<0b01101111,
"uxth" , UnOpFrag<(and node:$Src, 0x0000FFFF)>>;
defm UXTB16 : AI_unary_rrot<0b01101100,
"uxtb16", UnOpFrag<(and node:$Src, 0x00FF00FF)>>;
def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
defm UXTAB : AI_bin_rrot<0b01101110, "uxtab",
BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
defm UXTAH : AI_bin_rrot<0b01101111, "uxtah",
BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
// This isn't safe in general, the add is two 16-bit units, not a 32-bit add.
//defm UXTAB16 : xxx<"uxtab16", 0xff00ff>;
def SBFX : I<(outs GPR:$dst),
(ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
Evan Cheng
committed
"sbfx", "\t$dst, $src, $lsb, $width", "", []>,
Requires<[IsARM, HasV6T2]> {
let Inst{27-21} = 0b0111101;
let Inst{6-4} = 0b101;
}
def UBFX : I<(outs GPR:$dst),
(ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iALUi,
Evan Cheng
committed
"ubfx", "\t$dst, $src, $lsb, $width", "", []>,
Requires<[IsARM, HasV6T2]> {
let Inst{27-21} = 0b0111111;
let Inst{6-4} = 0b101;
}
//===----------------------------------------------------------------------===//
// Arithmetic Instructions.
//
Jim Grosbach
committed
defm ADD : AsI1_bin_irs<0b0100, "add",
BinOpFrag<(add node:$LHS, node:$RHS)>, 1>;
Jim Grosbach
committed
defm SUB : AsI1_bin_irs<0b0010, "sub",
BinOpFrag<(sub node:$LHS, node:$RHS)>>;
// ADD and SUB with 's' bit set.
defm ADDS : AI1_bin_s_irs<0b0100, "adds",
BinOpFrag<(addc node:$LHS, node:$RHS)>, 1>;
defm SUBS : AI1_bin_s_irs<0b0010, "subs",
Evan Cheng
committed
BinOpFrag<(subc node:$LHS, node:$RHS)>>;
Evan Cheng
committed
defm ADC : AI1_adde_sube_irs<0b0101, "adc",
Jim Grosbach
committed
BinOpFrag<(adde_dead_carry node:$LHS, node:$RHS)>, 1>;
Evan Cheng
committed
defm SBC : AI1_adde_sube_irs<0b0110, "sbc",
Jim Grosbach
committed
BinOpFrag<(sube_dead_carry node:$LHS, node:$RHS)>>;
defm ADCS : AI1_adde_sube_s_irs<0b0101, "adcs",
Jim Grosbach
committed
BinOpFrag<(adde_live_carry node:$LHS, node:$RHS)>, 1>;
defm SBCS : AI1_adde_sube_s_irs<0b0110, "sbcs",
Jim Grosbach
committed
BinOpFrag<(sube_live_carry node:$LHS, node:$RHS) >>;
// These don't define reg/reg forms, because they are handled above.
Evan Cheng
committed
def RSBri : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
Evan Cheng
committed
IIC_iALUi, "rsb", "\t$dst, $a, $b",
Evan Cheng
committed
[(set GPR:$dst, (sub so_imm:$b, GPR:$a))]> {
let Inst{25} = 1;
}
Evan Cheng
committed
Evan Cheng
committed
def RSBrs : AsI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
Evan Cheng
committed
IIC_iALUsr, "rsb", "\t$dst, $a, $b",
[(set GPR:$dst, (sub so_reg:$b, GPR:$a))]> {
let Inst{25} = 0;
}
// RSB with 's' bit set.
Evan Cheng
committed
let Defs = [CPSR] in {
Evan Cheng
committed
def RSBSri : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_imm:$b), DPFrm,
IIC_iALUi, "rsbs", "\t$dst, $a, $b",
Evan Cheng
committed
[(set GPR:$dst, (subc so_imm:$b, GPR:$a))]> {
let Inst{20} = 1;
Evan Cheng
committed
let Inst{25} = 1;
}
Evan Cheng
committed
def RSBSrs : AI1<0b0011, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
IIC_iALUsr, "rsbs", "\t$dst, $a, $b",
[(set GPR:$dst, (subc so_reg:$b, GPR:$a))]> {
let Inst{20} = 1;
let Inst{25} = 0;
}
Evan Cheng
committed
}
Evan Cheng
committed
let Uses = [CPSR] in {
def RSCri : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
Evan Cheng
committed
DPFrm, IIC_iALUi, "rsc", "\t$dst, $a, $b",
Jim Grosbach
committed
[(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
Requires<[IsARM]> {
Evan Cheng
committed
let Inst{25} = 1;
}
Evan Cheng
committed
def RSCrs : AsI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
Evan Cheng
committed
DPSoRegFrm, IIC_iALUsr, "rsc", "\t$dst, $a, $b",
Jim Grosbach
committed
[(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
Requires<[IsARM]> {
let Inst{25} = 0;
}
Evan Cheng
committed
}
// FIXME: Allow these to be predicated.
Evan Cheng
committed
let Defs = [CPSR], Uses = [CPSR] in {
def RSCSri : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_imm:$b),
Evan Cheng
committed
DPFrm, IIC_iALUi, "rscs\t$dst, $a, $b",
Jim Grosbach
committed
[(set GPR:$dst, (sube_dead_carry so_imm:$b, GPR:$a))]>,
Requires<[IsARM]> {
let Inst{20} = 1;
Evan Cheng
committed
let Inst{25} = 1;
}
Evan Cheng
committed
def RSCSrs : AXI1<0b0111, (outs GPR:$dst), (ins GPR:$a, so_reg:$b),
Evan Cheng
committed
DPSoRegFrm, IIC_iALUsr, "rscs\t$dst, $a, $b",
Jim Grosbach
committed
[(set GPR:$dst, (sube_dead_carry so_reg:$b, GPR:$a))]>,
Requires<[IsARM]> {
let Inst{20} = 1;
let Inst{25} = 0;
}
Evan Cheng
committed
}
// (sub X, imm) gets canonicalized to (add X, -imm). Match this form.
def : ARMPat<(add GPR:$src, so_imm_neg:$imm),
(SUBri GPR:$src, so_imm_neg:$imm)>;
//def : ARMPat<(addc GPR:$src, so_imm_neg:$imm),
// (SUBSri GPR:$src, so_imm_neg:$imm)>;
//def : ARMPat<(adde GPR:$src, so_imm_neg:$imm),
// (SBCri GPR:$src, so_imm_neg:$imm)>;
// Note: These are implemented in C++ code, because they have to generate
// ADD/SUBrs instructions, which use a complex pattern that a xform function
// cannot produce.
// (mul X, 2^n+1) -> (add (X << n), X)
// (mul X, 2^n-1) -> (rsb X, (X << n))
// Saturating adds/subtracts -- for disassembly only
Johnny Chen
committed
// GPR:$dst = GPR:$a op GPR:$b
class AQI<bits<8> op27_20, bits<4> op7_4, string opc>
Johnny Chen
committed
: AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b), DPFrm, IIC_iALUr,
opc, "\t$dst, $a, $b",
[/* For disassembly only; pattern left blank */]> {
let Inst{27-20} = op27_20;
let Inst{7-4} = op7_4;
}
def QADD : AQI<0b00010000, 0b0101, "qadd">;
def QADD16 : AQI<0b01100010, 0b0001, "qadd16">;
def QADD8 : AQI<0b01100010, 0b1001, "qadd8">;
def QASX : AQI<0b01100010, 0b0011, "qasx">;
def QDADD : AQI<0b00010100, 0b0101, "qdadd">;
def QDSUB : AQI<0b00010110, 0b0101, "qdsub">;
def QSAX : AQI<0b01100010, 0b0101, "qsax">;
def QSUB : AQI<0b00010010, 0b0101, "qsub">;
def QSUB16 : AQI<0b01100010, 0b0111, "qsub16">;
def QSUB8 : AQI<0b01100010, 0b1111, "qsub8">;
def UQADD16 : AQI<0b01100110, 0b0001, "uqadd16">;
def UQADD8 : AQI<0b01100110, 0b1001, "uqadd8">;
def UQASX : AQI<0b01100110, 0b0011, "uqasx">;
def UQSAX : AQI<0b01100110, 0b0101, "uqsax">;
def UQSUB16 : AQI<0b01100110, 0b0111, "uqsub16">;
def UQSUB8 : AQI<0b01100110, 0b1111, "uqsub8">;
//===----------------------------------------------------------------------===//
// Bitwise Instructions.
//
Jim Grosbach
committed
defm AND : AsI1_bin_irs<0b0000, "and",
BinOpFrag<(and node:$LHS, node:$RHS)>, 1>;
Jim Grosbach
committed
defm ORR : AsI1_bin_irs<0b1100, "orr",
BinOpFrag<(or node:$LHS, node:$RHS)>, 1>;
Jim Grosbach
committed
defm EOR : AsI1_bin_irs<0b0001, "eor",
BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
Jim Grosbach
committed
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, IIC_iUNAsi,
Evan Cheng
committed
"bfc", "\t$dst, $imm", "$src = $dst",
[(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
Requires<[IsARM, HasV6T2]> {
let Inst{27-21} = 0b0111110;
let Inst{6-0} = 0b0011111;
}
// A8.6.18 BFI - Bitfield insert (Encoding A1)
// Added for disassembler with the pattern field purposely left blank.
def BFI : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
"bfi", "\t$dst, $src, $imm", "",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV6T2]> {
let Inst{27-21} = 0b0111110;
let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
}
def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMOVr,
Evan Cheng
committed
"mvn", "\t$dst, $src",
[(set GPR:$dst, (not GPR:$src))]>, UnaryDP {
Johnny Chen
committed
let Inst{25} = 0;
Johnny Chen
committed
let Inst{11-4} = 0b00000000;
Evan Cheng
committed
def MVNs : AsI1<0b1111, (outs GPR:$dst), (ins so_reg:$src), DPSoRegFrm,
Evan Cheng
committed
IIC_iMOVsr, "mvn", "\t$dst, $src",
Johnny Chen
committed
[(set GPR:$dst, (not so_reg:$src))]>, UnaryDP {
let Inst{25} = 0;
}
let isReMaterializable = 1, isAsCheapAsAMove = 1 in
def MVNi : AsI1<0b1111, (outs GPR:$dst), (ins so_imm:$imm), DPFrm,
Evan Cheng
committed
IIC_iMOVi, "mvn", "\t$dst, $imm",
Evan Cheng
committed
[(set GPR:$dst, so_imm_not:$imm)]>,UnaryDP {
let Inst{25} = 1;
}
def : ARMPat<(and GPR:$src, so_imm_not:$imm),
(BICri GPR:$src, so_imm_not:$imm)>;
Rafael Espindola
committed
//===----------------------------------------------------------------------===//
// Multiply Instructions.
//
def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL32, "mul", "\t$dst, $a, $b",
[(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
Evan Cheng
committed
def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng
committed
IIC_iMAC32, "mla", "\t$dst, $a, $b, $c",
[(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
David Goodwin
committed
def MLS : AMul1I<0b0000011, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng
committed
IIC_iMAC32, "mls", "\t$dst, $a, $b, $c",
[(set GPR:$dst, (sub GPR:$c, (mul GPR:$a, GPR:$b)))]>,
Requires<[IsARM, HasV6T2]>;
// Extra precision multiplies with low / high results
let neverHasSideEffects = 1 in {
Evan Cheng
committed
def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst),
(ins GPR:$a, GPR:$b), IIC_iMUL64,
Evan Cheng
committed
"smull", "\t$ldst, $hdst, $a, $b", []>;
Evan Cheng
committed
def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst),
(ins GPR:$a, GPR:$b), IIC_iMUL64,
Evan Cheng
committed
"umull", "\t$ldst, $hdst, $a, $b", []>;
Evan Cheng
committed
def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst),
(ins GPR:$a, GPR:$b), IIC_iMAC64,
Evan Cheng
committed
"smlal", "\t$ldst, $hdst, $a, $b", []>;
Evan Cheng
committed
def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst),
(ins GPR:$a, GPR:$b), IIC_iMAC64,
Evan Cheng
committed
"umlal", "\t$ldst, $hdst, $a, $b", []>;
Evan Cheng
committed
def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst),
(ins GPR:$a, GPR:$b), IIC_iMAC64,
Evan Cheng
committed
"umaal", "\t$ldst, $hdst, $a, $b", []>,
Evan Cheng
committed
Requires<[IsARM, HasV6]>;
} // neverHasSideEffects
// Most significant word multiply
Evan Cheng
committed
def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL32, "smmul", "\t$dst, $a, $b",
Evan Cheng
committed
[(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
Evan Cheng
committed
Requires<[IsARM, HasV6]> {
let Inst{7-4} = 0b0001;
let Inst{15-12} = 0b1111;
}
Evan Cheng
committed
Evan Cheng
committed
def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng
committed
IIC_iMAC32, "smmla", "\t$dst, $a, $b, $c",
Evan Cheng
committed
[(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
Evan Cheng
committed
Requires<[IsARM, HasV6]> {
let Inst{7-4} = 0b0001;
}
Evan Cheng
committed
def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
Evan Cheng
committed
IIC_iMAC32, "smmls", "\t$dst, $a, $b, $c",
[(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
Evan Cheng
committed
Requires<[IsARM, HasV6]> {
let Inst{7-4} = 0b1101;
}
Raul Herbster
committed
multiclass AI_smul<string opc, PatFrag opnode> {
def BB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL32, !strconcat(opc, "bb"), "\t$dst, $a, $b",
[(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
(sext_inreg GPR:$b, i16)))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 0;
}
Raul Herbster
committed
def BT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL32, !strconcat(opc, "bt"), "\t$dst, $a, $b",
[(set GPR:$dst, (opnode (sext_inreg GPR:$a, i16),
(sra GPR:$b, (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 1;
}
Raul Herbster
committed
def TB : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL32, !strconcat(opc, "tb"), "\t$dst, $a, $b",
[(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
(sext_inreg GPR:$b, i16)))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 0;
}
Raul Herbster
committed
def TT : AMulxyI<0b0001011, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL32, !strconcat(opc, "tt"), "\t$dst, $a, $b",
[(set GPR:$dst, (opnode (sra GPR:$a, (i32 16)),
(sra GPR:$b, (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 1;
}
Raul Herbster
committed
def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL16, !strconcat(opc, "wb"), "\t$dst, $a, $b",
[(set GPR:$dst, (sra (opnode GPR:$a,
(sext_inreg GPR:$b, i16)), (i32 16)))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 0;
}
Raul Herbster
committed
def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b),
Evan Cheng
committed
IIC_iMUL16, !strconcat(opc, "wt"), "\t$dst, $a, $b",
(sra GPR:$b, (i32 16))), (i32 16)))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 1;
}
Raul Herbster
committed
multiclass AI_smla<string opc, PatFrag opnode> {
def BB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "bb"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc,
(opnode (sext_inreg GPR:$a, i16),
(sext_inreg GPR:$b, i16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 0;
}
Raul Herbster
committed
def BT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "bt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sext_inreg GPR:$a, i16),
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 1;
}
Raul Herbster
committed
def TB : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "tb"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
(sext_inreg GPR:$b, i16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 0;
}
Raul Herbster
committed
def TT : AMulxyI<0b0001000, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "tt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (opnode (sra GPR:$a, (i32 16)),
(sra GPR:$b, (i32 16)))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 1;
}
def WB : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "wb"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
(sext_inreg GPR:$b, i16)), (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 0;
}
Raul Herbster
committed
def WT : AMulxyI<0b0001001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
Evan Cheng
committed
IIC_iMAC16, !strconcat(opc, "wt"), "\t$dst, $a, $b, $acc",
[(set GPR:$dst, (add GPR:$acc, (sra (opnode GPR:$a,
(sra GPR:$b, (i32 16))), (i32 16))))]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 1;
}
Raul Herbster
committed
defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
// Halfword multiply accumulate long: SMLAL<x><y> -- for disassembly only
def SMLALBB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
IIC_iMAC64, "smlalbb", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 0;
}
def SMLALBT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
IIC_iMAC64, "smlalbt", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 0;
let Inst{6} = 1;
}
def SMLALTB : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
IIC_iMAC64, "smlaltb", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 0;
}
def SMLALTT : AMulxyI<0b0001010,(outs GPR:$ldst,GPR:$hdst),(ins GPR:$a,GPR:$b),
IIC_iMAC64, "smlaltt", "\t$ldst, $hdst, $a, $b",
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV5TE]> {
let Inst{5} = 1;
let Inst{6} = 1;
}
// TODO: Dual halfword multiple: SMUAD, SMUSD, SMLAD, SMLSD, SMLALD, SMLSLD
//===----------------------------------------------------------------------===//
// Misc. Arithmetic Instructions.
//
def CLZ : AMiscA1I<0b000010110, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng
committed
"clz", "\t$dst, $src",
[(set GPR:$dst, (ctlz GPR:$src))]>, Requires<[IsARM, HasV5T]> {
let Inst{7-4} = 0b0001;
let Inst{11-8} = 0b1111;
let Inst{19-16} = 0b1111;
}
def RBIT : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng
committed
"rbit", "\t$dst, $src",
[(set GPR:$dst, (ARMrbit GPR:$src))]>,
Requires<[IsARM, HasV6T2]> {
let Inst{7-4} = 0b0011;
let Inst{11-8} = 0b1111;
let Inst{19-16} = 0b1111;
}
def REV : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng
committed
"rev", "\t$dst, $src",
[(set GPR:$dst, (bswap GPR:$src))]>, Requires<[IsARM, HasV6]> {
let Inst{7-4} = 0b0011;
let Inst{11-8} = 0b1111;
let Inst{19-16} = 0b1111;
}
def REV16 : AMiscA1I<0b01101011, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng
committed
"rev16", "\t$dst, $src",
(or (and (srl GPR:$src, (i32 8)), 0xFF),
(or (and (shl GPR:$src, (i32 8)), 0xFF00),
(or (and (srl GPR:$src, (i32 8)), 0xFF0000),
(and (shl GPR:$src, (i32 8)), 0xFF000000)))))]>,
Requires<[IsARM, HasV6]> {
let Inst{7-4} = 0b1011;
let Inst{11-8} = 0b1111;
let Inst{19-16} = 0b1111;
}
def REVSH : AMiscA1I<0b01101111, (outs GPR:$dst), (ins GPR:$src), IIC_iUNAr,
Evan Cheng
committed
"revsh", "\t$dst, $src",
(or (srl (and GPR:$src, 0xFF00), (i32 8)),
(shl GPR:$src, (i32 8))), i16))]>,
Requires<[IsARM, HasV6]> {
let Inst{7-4} = 0b1011;
let Inst{11-8} = 0b1111;
let Inst{19-16} = 0b1111;
}
def PKHBT : AMiscA1I<0b01101000, (outs GPR:$dst),
(ins GPR:$src1, GPR:$src2, i32imm:$shamt),
Evan Cheng
committed
IIC_iALUsi, "pkhbt", "\t$dst, $src1, $src2, LSL $shamt",
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF),
(and (shl GPR:$src2, (i32 imm:$shamt)),
0xFFFF0000)))]>,
Requires<[IsARM, HasV6]> {
let Inst{6-4} = 0b001;
}
// Alternate cases for PKHBT where identities eliminate some nodes.
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (and GPR:$src2, 0xFFFF0000)),
(PKHBT GPR:$src1, GPR:$src2, 0)>;
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF), (shl GPR:$src2, imm16_31:$shamt)),
(PKHBT GPR:$src1, GPR:$src2, imm16_31:$shamt)>;
def PKHTB : AMiscA1I<0b01101000, (outs GPR:$dst),
(ins GPR:$src1, GPR:$src2, i32imm:$shamt),
Evan Cheng
committed
IIC_iALUsi, "pkhtb", "\t$dst, $src1, $src2, ASR $shamt",
[(set GPR:$dst, (or (and GPR:$src1, 0xFFFF0000),
(and (sra GPR:$src2, imm16_31:$shamt),
0xFFFF)))]>, Requires<[IsARM, HasV6]> {
let Inst{6-4} = 0b101;
}
// 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 : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000), (srl GPR:$src2, (i32 16))),
(PKHTB GPR:$src1, GPR:$src2, 16)>;
def : ARMV6Pat<(or (and GPR:$src1, 0xFFFF0000),
(and (srl GPR:$src2, imm1_15:$shamt), 0xFFFF)),
(PKHTB GPR:$src1, GPR:$src2, imm1_15:$shamt)>;
//===----------------------------------------------------------------------===//
// Comparison Instructions...
//
Jim Grosbach
committed
defm CMP : AI1_cmp_irs<0b1010, "cmp",
BinOpFrag<(ARMcmp node:$LHS, node:$RHS)>>;
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
// Compare-to-zero still works out, just not the relationals
//defm CMN : AI1_cmp_irs<0b1011, "cmn",
// BinOpFrag<(ARMcmp node:$LHS,(ineg node:$RHS))>>;
// Note that TST/TEQ don't set all the same flags that CMP does!
Evan Cheng
committed
defm TST : AI1_cmp_irs<0b1000, "tst",
David Goodwin
committed
BinOpFrag<(ARMcmpZ (and node:$LHS, node:$RHS), 0)>, 1>;
Evan Cheng
committed
defm TEQ : AI1_cmp_irs<0b1001, "teq",
David Goodwin
committed
BinOpFrag<(ARMcmpZ (xor node:$LHS, node:$RHS), 0)>, 1>;
Lauro Ramos Venancio
committed
David Goodwin
committed
defm CMPz : AI1_cmp_irs<0b1010, "cmp",
BinOpFrag<(ARMcmpZ node:$LHS, node:$RHS)>>;
defm CMNz : AI1_cmp_irs<0b1011, "cmn",
BinOpFrag<(ARMcmpZ node:$LHS,(ineg node:$RHS))>>;
//def : ARMPat<(ARMcmp GPR:$src, so_imm_neg:$imm),
// (CMNri GPR:$src, so_imm_neg:$imm)>;
Lauro Ramos Venancio
committed
David Goodwin
committed
def : ARMPat<(ARMcmpZ GPR:$src, so_imm_neg:$imm),
(CMNzri GPR:$src, so_imm_neg:$imm)>;
Lauro Ramos Venancio
committed
// 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. :(
Evan Cheng
committed
def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm,
Evan Cheng
committed
IIC_iCMOVr, "mov", "\t$dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
RegConstraint<"$false = $dst">, UnaryDP {
Johnny Chen
committed
let Inst{11-4} = 0b00000000;
let Inst{25} = 0;
}
Evan Cheng
committed
def MOVCCs : AI1<0b1101, (outs GPR:$dst),
(ins GPR:$false, so_reg:$true), DPSoRegFrm, IIC_iCMOVsr,
Evan Cheng
committed
"mov", "\t$dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
RegConstraint<"$false = $dst">, UnaryDP {
let Inst{25} = 0;
}
Evan Cheng
committed
def MOVCCi : AI1<0b1101, (outs GPR:$dst),
(ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi,
Evan Cheng
committed
"mov", "\t$dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
Evan Cheng
committed
RegConstraint<"$false = $dst">, UnaryDP {
let Inst{25} = 1;
Evan Cheng
committed
}
Jim Grosbach
committed
//===----------------------------------------------------------------------===//
// Atomic operations intrinsics
//
// memory barriers protect the atomic sequences
let hasSideEffects = 1 in {
def Int_MemBarrierV7 : AInoP<(outs), (ins),
Jim Grosbach
committed
Pseudo, NoItinerary,
"dmb", "",
Jim Grosbach
committed
Requires<[IsARM, HasV7]> {
let Inst{31-4} = 0xf57ff05;
// FIXME: add support for options other than a full system DMB
// See DMB disassembly-only variants below.
Jim Grosbach
committed
def Int_SyncBarrierV7 : AInoP<(outs), (ins),
Jim Grosbach
committed
Pseudo, NoItinerary,
"dsb", "",
Jim Grosbach
committed
Requires<[IsARM, HasV7]> {
let Inst{31-4} = 0xf57ff04;
// FIXME: add support for options other than a full system DSB
// See DSB disassembly-only variants below.
def Int_MemBarrierV6 : AInoP<(outs), (ins GPR:$zero),
Pseudo, NoItinerary,
"mcr", "\tp15, 0, $zero, c7, c10, 5",
[(ARMMemBarrierV6 GPR:$zero)]>,
Requires<[IsARM, HasV6]> {
// FIXME: add support for options other than a full system DMB
// FIXME: add encoding
}
def Int_SyncBarrierV6 : AInoP<(outs), (ins GPR:$zero),
Pseudo, NoItinerary,
[(ARMSyncBarrierV6 GPR:$zero)]>,
Requires<[IsARM, HasV6]> {
// FIXME: add support for options other than a full system DSB
// FIXME: add encoding
}
Jim Grosbach
committed
}
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
// Helper class for multiclass MemB -- for disassembly only
class AMBI<string opc, string asm>
: AInoP<(outs), (ins), MiscFrm, NoItinerary, opc, asm,
[/* For disassembly only; pattern left blank */]>,
Requires<[IsARM, HasV7]> {
let Inst{31-20} = 0xf57;
}
multiclass MemB<bits<4> op7_4, string opc> {
def st : AMBI<opc, "\tst"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b1110;
}
def ish : AMBI<opc, "\tish"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b1011;
}
def ishst : AMBI<opc, "\tishst"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b1010;
}
def nsh : AMBI<opc, "\tnsh"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b0111;
}
def nshst : AMBI<opc, "\tnshst"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b0110;
}
def osh : AMBI<opc, "\tosh"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b0011;
}
def oshst : AMBI<opc, "\toshst"> {
let Inst{7-4} = op7_4;
let Inst{3-0} = 0b0010;
}
}
// These DMB variants are for disassembly only.
defm DMB : MemB<0b0101, "dmb">;
// These DSB variants are for disassembly only.
defm DSB : MemB<0b0100, "dsb">;
// ISB has only full system option -- for disassembly only
def ISBsy : AMBI<"isb", ""> {
let Inst{7-4} = 0b0110;
let Inst{3-0} = 0b1111;
}
Jim Grosbach
committed
let Uses = [CPSR] in {
def ATOMIC_LOAD_ADD_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_ADD_I8 PSEUDO!",
[(set GPR:$dst, (atomic_load_add_8 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_SUB_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_SUB_I8 PSEUDO!",
[(set GPR:$dst, (atomic_load_sub_8 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_AND_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_AND_I8 PSEUDO!",
[(set GPR:$dst, (atomic_load_and_8 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_OR_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,
"${:comment} ATOMIC_LOAD_OR_I8 PSEUDO!",
[(set GPR:$dst, (atomic_load_or_8 GPR:$ptr, GPR:$incr))]>;
def ATOMIC_LOAD_XOR_I8 : PseudoInst<
(outs GPR:$dst), (ins GPR:$ptr, GPR:$incr), NoItinerary,