aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMInstrThumb.td
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-01-01 10:31:22 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-01-01 10:31:22 +0000
commit1e7804dbd25b8dbf534c850355d70ad215206f4b (patch)
treedba00119388b84f9f44e6ec5e9129f807fd79ca3 /lib/Target/ARM/ARMInstrThumb.td
parent571945e6affd20b19264ec22495da418d0fbdbb4 (diff)
downloadsrc-1e7804dbd25b8dbf534c850355d70ad215206f4b.tar.gz
src-1e7804dbd25b8dbf534c850355d70ad215206f4b.zip
Update LLVM to 92395.
Notes
Notes: svn path=/vendor/llvm/dist/; revision=201360
Diffstat (limited to 'lib/Target/ARM/ARMInstrThumb.td')
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td320
1 files changed, 214 insertions, 106 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index 9306bdb4b70a..34d7d8f6eff5 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -113,7 +113,7 @@ def t_addrmode_s1 : Operand<i32>,
def t_addrmode_sp : Operand<i32>,
ComplexPattern<i32, 2, "SelectThumbAddrModeSP", []> {
let PrintMethod = "printThumbAddrModeSPOperand";
- let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm);
+ let MIOperandInfo = (ops JustSP:$base, i32imm:$offsimm);
}
//===----------------------------------------------------------------------===//
@@ -136,31 +136,46 @@ PseudoInst<(outs), (ins i32imm:$amt), NoItinerary,
let isNotDuplicable = 1 in
def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr,
"\n$cp:\n\tadd\t$dst, pc",
- [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>;
+ [(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>,
+ T1Special<{0,0,?,?}> {
+ let Inst{6-3} = 0b1111; // A8.6.6 Rm = pc
+}
// PC relative add.
def tADDrPCi : T1I<(outs tGPR:$dst), (ins t_imm_s4:$rhs), IIC_iALUi,
- "add\t$dst, pc, $rhs", []>;
+ "add\t$dst, pc, $rhs", []>,
+ T1Encoding<{1,0,1,0,0,?}>; // A6.2 & A8.6.10
// ADD rd, sp, #imm8
def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, t_imm_s4:$rhs), IIC_iALUi,
- "add\t$dst, $sp, $rhs", []>;
+ "add\t$dst, $sp, $rhs", []>,
+ T1Encoding<{1,0,1,0,1,?}>; // A6.2 & A8.6.8
// ADD sp, sp, #imm7
def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi,
- "add\t$dst, $rhs", []>;
+ "add\t$dst, $rhs", []>,
+ T1Misc<{0,0,0,0,0,?,?}>; // A6.2.5 & A8.6.8
// SUB sp, sp, #imm7
def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, t_imm_s4:$rhs), IIC_iALUi,
- "sub\t$dst, $rhs", []>;
+ "sub\t$dst, $rhs", []>,
+ T1Misc<{0,0,0,0,1,?,?}>; // A6.2.5 & A8.6.215
// ADD rm, sp
def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
- "add\t$dst, $rhs", []>;
+ "add\t$dst, $rhs", []>,
+ T1Special<{0,0,?,?}> {
+ let Inst{6-3} = 0b1101; // A8.6.9 Encoding T1
+}
// ADD sp, rm
def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
- "add\t$dst, $rhs", []>;
+ "add\t$dst, $rhs", []>,
+ T1Special<{0,0,?,?}> {
+ // A8.6.9 Encoding T2
+ let Inst{7} = 1;
+ let Inst{2-0} = 0b101;
+}
// Pseudo instruction that will expand into a tSUBspi + a copy.
let usesCustomInserter = 1 in { // Expanded after instruction selection.
@@ -180,22 +195,32 @@ def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
//
let isReturn = 1, isTerminator = 1, isBarrier = 1 in {
- def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>;
+ def tBX_RET : TI<(outs), (ins), IIC_Br, "bx\tlr", [(ARMretflag)]>,
+ T1Special<{1,1,0,?}> { // A6.2.3 & A8.6.25
+ let Inst{6-3} = 0b1110; // Rm = lr
+ }
// Alternative return instruction used by vararg functions.
- def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>;
+ def tBX_RET_vararg : TI<(outs), (ins tGPR:$target), IIC_Br, "bx\t$target", []>,
+ T1Special<{1,1,0,?}>; // A6.2.3 & A8.6.25
}
// Indirect branches
let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
def tBRIND : TI<(outs), (ins GPR:$dst), IIC_Br, "mov\tpc, $dst",
- [(brind GPR:$dst)]>;
+ [(brind GPR:$dst)]>,
+ T1Special<{1,0,?,?}> {
+ // <Rd> = pc
+ let Inst{7} = 1;
+ let Inst{2-0} = 0b111;
+ }
}
// FIXME: remove when we have a way to marking a MI with these properties.
let isReturn = 1, isTerminator = 1, isBarrier = 1, mayLoad = 1,
hasExtraDefRegAllocReq = 1 in
def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
- "pop${p}\t$wb", []>;
+ "pop${p}\t$wb", []>,
+ T1Misc<{1,1,0,?,?,?,?}>;
let isCall = 1,
Defs = [R0, R1, R2, R3, R12, LR,
@@ -203,25 +228,29 @@ let isCall = 1,
D16, D17, D18, D19, D20, D21, D22, D23,
D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
// Also used for Thumb2
- def tBL : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br,
- "bl\t${func:call}",
- [(ARMtcall tglobaladdr:$func)]>,
+ def tBL : TIx2<0b11110, 0b11, 1,
+ (outs), (ins i32imm:$func, variable_ops), IIC_Br,
+ "bl\t${func:call}",
+ [(ARMtcall tglobaladdr:$func)]>,
Requires<[IsThumb, IsNotDarwin]>;
// ARMv5T and above, also used for Thumb2
- def tBLXi : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br,
- "blx\t${func:call}",
- [(ARMcall tglobaladdr:$func)]>,
+ def tBLXi : TIx2<0b11110, 0b11, 0,
+ (outs), (ins i32imm:$func, variable_ops), IIC_Br,
+ "blx\t${func:call}",
+ [(ARMcall tglobaladdr:$func)]>,
Requires<[IsThumb, HasV5T, IsNotDarwin]>;
// Also used for Thumb2
def tBLXr : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br,
"blx\t$func",
[(ARMtcall GPR:$func)]>,
- Requires<[IsThumb, HasV5T, IsNotDarwin]>;
+ Requires<[IsThumb, HasV5T, IsNotDarwin]>,
+ T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24;
// ARMv4T
- def tBX : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br,
+ def tBX : TIx2<{?,?,?,?,?}, {?,?}, ?,
+ (outs), (ins tGPR:$func, variable_ops), IIC_Br,
"mov\tlr, pc\n\tbx\t$func",
[(ARMcall_nolink tGPR:$func)]>,
Requires<[IsThumb1Only, IsNotDarwin]>;
@@ -234,27 +263,31 @@ let isCall = 1,
D16, D17, D18, D19, D20, D21, D22, D23,
D24, D25, D26, D27, D28, D29, D30, D31, CPSR, FPSCR] in {
// Also used for Thumb2
- def tBLr9 : TIx2<(outs), (ins i32imm:$func, variable_ops), IIC_Br,
+ def tBLr9 : TIx2<0b11110, 0b11, 1,
+ (outs), (ins i32imm:$func, variable_ops), IIC_Br,
"bl\t${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), IIC_Br,
+ def tBLXi_r9 : TIx2<0b11110, 0b11, 0,
+ (outs), (ins i32imm:$func, variable_ops), IIC_Br,
"blx\t${func:call}",
[(ARMcall tglobaladdr:$func)]>,
Requires<[IsThumb, HasV5T, IsDarwin]>;
// Also used for Thumb2
def tBLXr_r9 : TI<(outs), (ins GPR:$func, variable_ops), IIC_Br,
- "blx\t$func",
- [(ARMtcall GPR:$func)]>,
- Requires<[IsThumb, HasV5T, IsDarwin]>;
+ "blx\t$func",
+ [(ARMtcall GPR:$func)]>,
+ Requires<[IsThumb, HasV5T, IsDarwin]>,
+ T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24
// ARMv4T
- def tBXr9 : TIx2<(outs), (ins tGPR:$func, variable_ops), IIC_Br,
- "mov\tlr, pc\n\tbx\t$func",
- [(ARMcall_nolink tGPR:$func)]>,
+ def tBXr9 : TIx2<{?,?,?,?,?}, {?,?}, ?,
+ (outs), (ins tGPR:$func, variable_ops), IIC_Br,
+ "mov\tlr, pc\n\tbx\t$func",
+ [(ARMcall_nolink tGPR:$func)]>,
Requires<[IsThumb1Only, IsDarwin]>;
}
@@ -262,17 +295,22 @@ let isBranch = 1, isTerminator = 1 in {
let isBarrier = 1 in {
let isPredicable = 1 in
def tB : T1I<(outs), (ins brtarget:$target), IIC_Br,
- "b\t$target", [(br bb:$target)]>;
+ "b\t$target", [(br bb:$target)]>,
+ T1Encoding<{1,1,1,0,0,?}>;
// Far jump
let Defs = [LR] in
- def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br,
+ def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br,
"bl\t$target\t@ far jump",[]>;
def tBR_JTr : T1JTI<(outs),
(ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
IIC_Br, "mov\tpc, $target\n\t.align\t2\n$jt",
- [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>;
+ [(ARMbrjt tGPR:$target, tjumptable:$jt, imm:$id)]>,
+ Encoding16 {
+ let Inst{15-7} = 0b010001101;
+ let Inst{2-0} = 0b111;
+ }
}
}
@@ -281,15 +319,18 @@ let isBranch = 1, isTerminator = 1 in {
let isBranch = 1, isTerminator = 1 in
def tBcc : T1I<(outs), (ins brtarget:$target, pred:$cc), IIC_Br,
"b$cc\t$target",
- [/*(ARMbrcond bb:$target, imm:$cc)*/]>;
+ [/*(ARMbrcond bb:$target, imm:$cc)*/]>,
+ T1Encoding<{1,1,0,1,?,?}>;
// Compare and branch on zero / non-zero
let isBranch = 1, isTerminator = 1 in {
def tCBZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br,
- "cbz\t$cmp, $target", []>;
+ "cbz\t$cmp, $target", []>,
+ T1Misc<{0,0,?,1,?,?,?}>;
def tCBNZ : T1I<(outs), (ins tGPR:$cmp, brtarget:$target), IIC_Br,
- "cbnz\t$cmp, $target", []>;
+ "cbnz\t$cmp, $target", []>,
+ T1Misc<{1,0,?,1,?,?,?}>;
}
//===----------------------------------------------------------------------===//
@@ -299,71 +340,85 @@ let isBranch = 1, isTerminator = 1 in {
let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr,
"ldr", "\t$dst, $addr",
- [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>;
+ [(set tGPR:$dst, (load t_addrmode_s4:$addr))]>,
+ T1LdSt<0b100>;
def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr,
"ldrb", "\t$dst, $addr",
- [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>;
+ [(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>,
+ T1LdSt<0b110>;
def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr,
"ldrh", "\t$dst, $addr",
- [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>;
+ [(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>,
+ T1LdSt<0b101>;
let AddedComplexity = 10 in
def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr,
"ldrsb", "\t$dst, $addr",
- [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>;
+ [(set tGPR:$dst, (sextloadi8 t_addrmode_rr:$addr))]>,
+ T1LdSt<0b011>;
let AddedComplexity = 10 in
def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr,
"ldrsh", "\t$dst, $addr",
- [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>;
+ [(set tGPR:$dst, (sextloadi16 t_addrmode_rr:$addr))]>,
+ T1LdSt<0b111>;
let canFoldAsLoad = 1 in
def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi,
"ldr", "\t$dst, $addr",
- [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>;
+ [(set tGPR:$dst, (load t_addrmode_sp:$addr))]>,
+ T1LdStSP<{1,?,?}>;
// 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), IIC_iLoadi,
- "ldr", "\t$dst, $addr", []>;
+ "ldr", "\t$dst, $addr", []>,
+ T1LdStSP<{1,?,?}>;
// Load tconstpool
// FIXME: Use ldr.n to work around a Darwin assembler bug.
let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in
def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
"ldr", ".n\t$dst, $addr",
- [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>;
+ [(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>,
+ T1Encoding<{0,1,0,0,1,?}>; // A6.2 & A8.6.59
// Special LDR for loads from non-pc-relative constpools.
let canFoldAsLoad = 1, mayLoad = 1, isReMaterializable = 1,
mayHaveSideEffects = 1 in
def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
- "ldr", "\t$dst, $addr", []>;
+ "ldr", "\t$dst, $addr", []>,
+ T1LdStSP<{1,?,?}>;
def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer,
"str", "\t$src, $addr",
- [(store tGPR:$src, t_addrmode_s4:$addr)]>;
+ [(store tGPR:$src, t_addrmode_s4:$addr)]>,
+ T1LdSt<0b000>;
def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer,
"strb", "\t$src, $addr",
- [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>;
+ [(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>,
+ T1LdSt<0b010>;
def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer,
"strh", "\t$src, $addr",
- [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>;
+ [(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>,
+ T1LdSt<0b001>;
def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei,
"str", "\t$src, $addr",
- [(store tGPR:$src, t_addrmode_sp:$addr)]>;
+ [(store tGPR:$src, t_addrmode_sp:$addr)]>,
+ T1LdStSP<{0,?,?}>;
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), IIC_iStorei,
- "str", "\t$src, $addr", []>;
+ "str", "\t$src, $addr", []>,
+ T1LdStSP<{0,?,?}>;
}
//===----------------------------------------------------------------------===//
@@ -375,21 +430,25 @@ let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
def tLDM : T1I<(outs),
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
IIC_iLoadm,
- "ldm${addr:submode}${p}\t$addr, $wb", []>;
+ "ldm${addr:submode}${p}\t$addr, $wb", []>,
+ T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53
let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
def tSTM : T1I<(outs),
(ins addrmode4:$addr, pred:$p, reglist:$wb, variable_ops),
IIC_iStorem,
- "stm${addr:submode}${p}\t$addr, $wb", []>;
+ "stm${addr:submode}${p}\t$addr, $wb", []>,
+ T1Encoding<{1,1,0,0,0,?}>; // A6.2 & A8.6.189
let mayLoad = 1, Uses = [SP], Defs = [SP], hasExtraDefRegAllocReq = 1 in
def tPOP : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
- "pop${p}\t$wb", []>;
+ "pop${p}\t$wb", []>,
+ T1Misc<{1,1,0,?,?,?,?}>;
let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in
def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
- "push${p}\t$wb", []>;
+ "push${p}\t$wb", []>,
+ T1Misc<{0,1,0,?,?,?,?}>;
//===----------------------------------------------------------------------===//
// Arithmetic Instructions.
@@ -399,82 +458,98 @@ def tPUSH : T1I<(outs), (ins pred:$p, reglist:$wb, variable_ops), IIC_Br,
let isCommutable = 1, Uses = [CPSR] in
def tADC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
"adc", "\t$dst, $rhs",
- [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (adde tGPR:$lhs, tGPR:$rhs))]>,
+ T1DataProcessing<0b0101>;
// Add immediate
def tADDi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
"add", "\t$dst, $lhs, $rhs",
- [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>;
+ [(set tGPR:$dst, (add tGPR:$lhs, imm0_7:$rhs))]>,
+ T1General<0b01110>;
def tADDi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
"add", "\t$dst, $rhs",
- [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>;
+ [(set tGPR:$dst, (add tGPR:$lhs, imm8_255:$rhs))]>,
+ T1General<{1,1,0,?,?}>;
// Add register
let isCommutable = 1 in
def tADDrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
"add", "\t$dst, $lhs, $rhs",
- [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>,
+ T1General<0b01100>;
let neverHasSideEffects = 1 in
def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
- "add", "\t$dst, $rhs", []>;
+ "add", "\t$dst, $rhs", []>,
+ T1Special<{0,0,?,?}>;
// And register
let isCommutable = 1 in
def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
"and", "\t$dst, $rhs",
- [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>,
+ T1DataProcessing<0b0000>;
// ASR immediate
def tASRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
"asr", "\t$dst, $lhs, $rhs",
- [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>;
+ [(set tGPR:$dst, (sra tGPR:$lhs, (i32 imm:$rhs)))]>,
+ T1General<{0,1,0,?,?}>;
// ASR register
def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
"asr", "\t$dst, $rhs",
- [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (sra tGPR:$lhs, tGPR:$rhs))]>,
+ T1DataProcessing<0b0100>;
// BIC register
def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
"bic", "\t$dst, $rhs",
- [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>;
+ [(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>,
+ T1DataProcessing<0b1110>;
// CMN register
let Defs = [CPSR] in {
def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
"cmn", "\t$lhs, $rhs",
- [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>;
-def tCMNZ : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
+ [(ARMcmp tGPR:$lhs, (ineg tGPR:$rhs))]>,
+ T1DataProcessing<0b1011>;
+def tCMNz : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
"cmn", "\t$lhs, $rhs",
- [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>;
+ [(ARMcmpZ tGPR:$lhs, (ineg tGPR:$rhs))]>,
+ T1DataProcessing<0b1011>;
}
// CMP immediate
let Defs = [CPSR] in {
def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi,
"cmp", "\t$lhs, $rhs",
- [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>;
+ [(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>,
+ T1General<{1,0,1,?,?}>;
def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi,
"cmp", "\t$lhs, $rhs",
- [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>;
-
+ [(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>,
+ T1General<{1,0,1,?,?}>;
}
// CMP register
let Defs = [CPSR] in {
def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
"cmp", "\t$lhs, $rhs",
- [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>;
+ [(ARMcmp tGPR:$lhs, tGPR:$rhs)]>,
+ T1DataProcessing<0b1010>;
def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
"cmp", "\t$lhs, $rhs",
- [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>;
+ [(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>,
+ T1DataProcessing<0b1010>;
def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
- "cmp", "\t$lhs, $rhs", []>;
+ "cmp", "\t$lhs, $rhs", []>,
+ T1Special<{0,1,?,?}>;
def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
- "cmp", "\t$lhs, $rhs", []>;
+ "cmp", "\t$lhs, $rhs", []>,
+ T1Special<{0,1,?,?}>;
}
@@ -482,32 +557,38 @@ def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
let isCommutable = 1 in
def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
"eor", "\t$dst, $rhs",
- [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>,
+ T1DataProcessing<0b0001>;
// LSL immediate
def tLSLri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
"lsl", "\t$dst, $lhs, $rhs",
- [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>;
+ [(set tGPR:$dst, (shl tGPR:$lhs, (i32 imm:$rhs)))]>,
+ T1General<{0,0,0,?,?}>;
// LSL register
def tLSLrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
"lsl", "\t$dst, $rhs",
- [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (shl tGPR:$lhs, tGPR:$rhs))]>,
+ T1DataProcessing<0b0010>;
// LSR immediate
def tLSRri : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iMOVsi,
"lsr", "\t$dst, $lhs, $rhs",
- [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>;
+ [(set tGPR:$dst, (srl tGPR:$lhs, (i32 imm:$rhs)))]>,
+ T1General<{0,0,1,?,?}>;
// LSR register
def tLSRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
"lsr", "\t$dst, $rhs",
- [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (srl tGPR:$lhs, tGPR:$rhs))]>,
+ T1DataProcessing<0b0011>;
// move register
def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
"mov", "\t$dst, $src",
- [(set tGPR:$dst, imm0_255:$src)]>;
+ [(set tGPR:$dst, imm0_255:$src)]>,
+ T1General<{1,0,0,?,?}>;
// TODO: A7-73: MOV(2) - mov setting flag.
@@ -515,42 +596,52 @@ def tMOVi8 : T1sI<(outs tGPR:$dst), (ins i32imm:$src), IIC_iMOVi,
let neverHasSideEffects = 1 in {
// FIXME: Make this predicable.
def tMOVr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
- "mov\t$dst, $src", []>;
+ "mov\t$dst, $src", []>,
+ T1Special<0b1000>;
let Defs = [CPSR] in
def tMOVSr : T1I<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
- "movs\t$dst, $src", []>;
+ "movs\t$dst, $src", []>, Encoding16 {
+ let Inst{15-6} = 0b0000000000;
+}
// FIXME: Make these predicable.
def tMOVgpr2tgpr : T1I<(outs tGPR:$dst), (ins GPR:$src), IIC_iMOVr,
- "mov\t$dst, $src", []>;
+ "mov\t$dst, $src", []>,
+ T1Special<{1,0,0,1}>;
def tMOVtgpr2gpr : T1I<(outs GPR:$dst), (ins tGPR:$src), IIC_iMOVr,
- "mov\t$dst, $src", []>;
+ "mov\t$dst, $src", []>,
+ T1Special<{1,0,1,0}>;
def tMOVgpr2gpr : T1I<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVr,
- "mov\t$dst, $src", []>;
+ "mov\t$dst, $src", []>,
+ T1Special<{1,0,1,1}>;
} // neverHasSideEffects
// multiply register
let isCommutable = 1 in
def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32,
"mul", "\t$dst, $rhs",
- [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>,
+ T1DataProcessing<0b1101>;
// move inverse register
def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
"mvn", "\t$dst, $src",
- [(set tGPR:$dst, (not tGPR:$src))]>;
+ [(set tGPR:$dst, (not tGPR:$src))]>,
+ T1DataProcessing<0b1111>;
// bitwise or register
let isCommutable = 1 in
def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
"orr", "\t$dst, $rhs",
- [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>,
+ T1DataProcessing<0b1100>;
// swaps
def tREV : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
"rev", "\t$dst, $src",
[(set tGPR:$dst, (bswap tGPR:$src))]>,
- Requires<[IsThumb1Only, HasV6]>;
+ Requires<[IsThumb1Only, HasV6]>,
+ T1Misc<{1,0,1,0,0,0,?}>;
def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
"rev16", "\t$dst, $src",
@@ -559,7 +650,8 @@ def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
(or (and (shl tGPR:$src, (i32 8)), 0xFF00),
(or (and (srl tGPR:$src, (i32 8)), 0xFF0000),
(and (shl tGPR:$src, (i32 8)), 0xFF000000)))))]>,
- Requires<[IsThumb1Only, HasV6]>;
+ Requires<[IsThumb1Only, HasV6]>,
+ T1Misc<{1,0,1,0,0,1,?}>;
def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
"revsh", "\t$dst, $src",
@@ -567,37 +659,44 @@ def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
(sext_inreg
(or (srl (and tGPR:$src, 0xFF00), (i32 8)),
(shl tGPR:$src, (i32 8))), i16))]>,
- Requires<[IsThumb1Only, HasV6]>;
+ Requires<[IsThumb1Only, HasV6]>,
+ T1Misc<{1,0,1,0,1,1,?}>;
// rotate right register
def tROR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
"ror", "\t$dst, $rhs",
- [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (rotr tGPR:$lhs, tGPR:$rhs))]>,
+ T1DataProcessing<0b0111>;
// negate register
def tRSB : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALUi,
"rsb", "\t$dst, $src, #0",
- [(set tGPR:$dst, (ineg tGPR:$src))]>;
+ [(set tGPR:$dst, (ineg tGPR:$src))]>,
+ T1DataProcessing<0b1001>;
// Subtract with carry register
let Uses = [CPSR] in
def tSBC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
"sbc", "\t$dst, $rhs",
- [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (sube tGPR:$lhs, tGPR:$rhs))]>,
+ T1DataProcessing<0b0110>;
// Subtract immediate
def tSUBi3 : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
"sub", "\t$dst, $lhs, $rhs",
- [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>;
+ [(set tGPR:$dst, (add tGPR:$lhs, imm0_7_neg:$rhs))]>,
+ T1General<0b01111>;
def tSUBi8 : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALUi,
"sub", "\t$dst, $rhs",
- [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>;
+ [(set tGPR:$dst, (add tGPR:$lhs, imm8_255_neg:$rhs))]>,
+ T1General<{1,1,1,?,?}>;
// subtract register
def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
"sub", "\t$dst, $lhs, $rhs",
- [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>;
+ [(set tGPR:$dst, (sub tGPR:$lhs, tGPR:$rhs))]>,
+ T1General<0b01101>;
// TODO: A7-96: STMIA - store multiple.
@@ -605,31 +704,36 @@ def tSUBrr : T1sI<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
"sxtb", "\t$dst, $src",
[(set tGPR:$dst, (sext_inreg tGPR:$src, i8))]>,
- Requires<[IsThumb1Only, HasV6]>;
+ Requires<[IsThumb1Only, HasV6]>,
+ T1Misc<{0,0,1,0,0,1,?}>;
// sign-extend short
def tSXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
"sxth", "\t$dst, $src",
[(set tGPR:$dst, (sext_inreg tGPR:$src, i16))]>,
- Requires<[IsThumb1Only, HasV6]>;
+ Requires<[IsThumb1Only, HasV6]>,
+ T1Misc<{0,0,1,0,0,0,?}>;
// test
let isCommutable = 1, Defs = [CPSR] in
def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
"tst", "\t$lhs, $rhs",
- [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>;
+ [(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>,
+ T1DataProcessing<0b1000>;
// zero-extend byte
def tUXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
"uxtb", "\t$dst, $src",
[(set tGPR:$dst, (and tGPR:$src, 0xFF))]>,
- Requires<[IsThumb1Only, HasV6]>;
+ Requires<[IsThumb1Only, HasV6]>,
+ T1Misc<{0,0,1,0,1,1,?}>;
// zero-extend short
def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
"uxth", "\t$dst, $src",
[(set tGPR:$dst, (and tGPR:$src, 0xFFFF))]>,
- Requires<[IsThumb1Only, HasV6]>;
+ Requires<[IsThumb1Only, HasV6]>,
+ T1Misc<{0,0,1,0,1,0,?}>;
// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation.
@@ -643,19 +747,23 @@ let usesCustomInserter = 1 in // Expanded after instruction selection.
// 16-bit movcc in IT blocks for Thumb2.
def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iCMOVr,
- "mov", "\t$dst, $rhs", []>;
+ "mov", "\t$dst, $rhs", []>,
+ T1Special<{1,0,?,?}>;
def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iCMOVi,
- "mov", "\t$dst, $rhs", []>;
+ "mov", "\t$dst, $rhs", []>,
+ T1General<{1,0,0,?,?}>;
// tLEApcrel - Load a pc-relative address into a register without offending the
// assembler.
def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label, pred:$p), IIC_iALUi,
- "adr$p\t$dst, #$label", []>;
+ "adr$p\t$dst, #$label", []>,
+ T1Encoding<{1,0,1,0,0,?}>; // A6.2 & A8.6.10
def tLEApcrelJT : T1I<(outs tGPR:$dst),
(ins i32imm:$label, nohash_imm:$id, pred:$p),
- IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>;
+ IIC_iALUi, "adr$p\t$dst, #${label}_${id}", []>,
+ T1Encoding<{1,0,1,0,0,?}>; // A6.2 & A8.6.10
//===----------------------------------------------------------------------===//
// TLS Instructions
@@ -664,9 +772,9 @@ def tLEApcrelJT : T1I<(outs tGPR:$dst),
// __aeabi_read_tp preserves the registers r1-r3.
let isCall = 1,
Defs = [R0, LR] in {
- def tTPsoft : TIx2<(outs), (ins), IIC_Br,
- "bl\t__aeabi_read_tp",
- [(set R0, ARMthread_pointer)]>;
+ def tTPsoft : TIx2<0b11110, 0b11, 1, (outs), (ins), IIC_Br,
+ "bl\t__aeabi_read_tp",
+ [(set R0, ARMthread_pointer)]>;
}
// SJLJ Exception handling intrinsics