aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/ARMInstrThumb.td
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM/ARMInstrThumb.td')
-rw-r--r--lib/Target/ARM/ARMInstrThumb.td216
1 files changed, 121 insertions, 95 deletions
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
index 87fdcef..2d387bb 100644
--- a/lib/Target/ARM/ARMInstrThumb.td
+++ b/lib/Target/ARM/ARMInstrThumb.td
@@ -126,14 +126,14 @@ def t_addrmode_sp : Operand<i32>,
// these will always be in pairs, and asserts if it finds otherwise. Better way?
let Defs = [SP], Uses = [SP], hasSideEffects = 1 in {
def tADJCALLSTACKUP :
-PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary,
- "${:comment} tADJCALLSTACKUP $amt1",
- [(ARMcallseq_end imm:$amt1, imm:$amt2)]>, Requires<[IsThumb1Only]>;
+PseudoInst<(outs), (ins i32imm:$amt1, i32imm:$amt2), NoItinerary, "",
+ [(ARMcallseq_end imm:$amt1, imm:$amt2)]>,
+ Requires<[IsThumb, IsThumb1Only]>;
def tADJCALLSTACKDOWN :
-PseudoInst<(outs), (ins i32imm:$amt), NoItinerary,
- "${:comment} tADJCALLSTACKDOWN $amt",
- [(ARMcallseq_start imm:$amt)]>, Requires<[IsThumb1Only]>;
+PseudoInst<(outs), (ins i32imm:$amt), NoItinerary, "",
+ [(ARMcallseq_start imm:$amt)]>,
+ Requires<[IsThumb, IsThumb1Only]>;
}
def tNOP : T1pI<(outs), (ins), NoItinerary, "nop", "",
@@ -207,9 +207,8 @@ def tCPS : T1I<(outs), (ins cps_opt:$opt), NoItinerary, "cps$opt",
T1Misc<0b0110011>;
// For both thumb1 and thumb2.
-let isNotDuplicable = 1 in
-def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr,
- "\n$cp:\n\tadd\t$dst, pc",
+let isNotDuplicable = 1, isCodeGenOnly = 1 in
+def tPICADD : TIt<(outs GPR:$dst), (ins GPR:$lhs, pclabel:$cp), IIC_iALUr, "",
[(set GPR:$dst, (ARMpic_add GPR:$lhs, imm:$cp))]>,
T1Special<{0,0,?,?}> {
let Inst{6-3} = 0b1111; // A8.6.6 Rm = pc
@@ -221,9 +220,13 @@ def tADDrPCi : T1I<(outs tGPR:$dst), (ins t_imm_s4:$rhs), IIC_iALUi,
T1Encoding<{1,0,1,0,0,?}>; // A6.2 & A8.6.10
// ADD rd, sp, #imm8
+// This is rematerializable, which is particularly useful for taking the
+// address of locals.
+let isReMaterializable = 1 in {
def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, t_imm_s4:$rhs), IIC_iALUi,
"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,
@@ -278,7 +281,8 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
// 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:$dsts, variable_ops), IIC_Br,
+def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$dsts, variable_ops),
+ IIC_iPop_Br,
"pop${p}\t$dsts", []>,
T1Misc<{1,1,0,?,?,?,?}>;
@@ -290,14 +294,14 @@ let isCall = 1,
// Also used for Thumb2
def tBL : TIx2<0b11110, 0b11, 1,
(outs), (ins i32imm:$func, variable_ops), IIC_Br,
- "bl\t${func:call}",
+ "bl\t$func",
[(ARMtcall tglobaladdr:$func)]>,
Requires<[IsThumb, IsNotDarwin]>;
// ARMv5T and above, also used for Thumb2
def tBLXi : TIx2<0b11110, 0b11, 0,
(outs), (ins i32imm:$func, variable_ops), IIC_Br,
- "blx\t${func:call}",
+ "blx\t$func",
[(ARMcall tglobaladdr:$func)]>,
Requires<[IsThumb, HasV5T, IsNotDarwin]>;
@@ -309,11 +313,12 @@ let isCall = 1,
T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24;
// ARMv4T
+ let isCodeGenOnly = 1 in
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]>;
+ Requires<[IsThumb, IsThumb1Only, IsNotDarwin]>;
}
// On Darwin R9 is call-clobbered.
@@ -325,14 +330,14 @@ let isCall = 1,
// Also used for Thumb2
def tBLr9 : TIx2<0b11110, 0b11, 1,
(outs), (ins i32imm:$func, variable_ops), IIC_Br,
- "bl\t${func:call}",
+ "bl\t$func",
[(ARMtcall tglobaladdr:$func)]>,
Requires<[IsThumb, IsDarwin]>;
// ARMv5T and above, also used for Thumb2
def tBLXi_r9 : TIx2<0b11110, 0b11, 0,
(outs), (ins i32imm:$func, variable_ops), IIC_Br,
- "blx\t${func:call}",
+ "blx\t$func",
[(ARMcall tglobaladdr:$func)]>,
Requires<[IsThumb, HasV5T, IsDarwin]>;
@@ -344,11 +349,12 @@ let isCall = 1,
T1Special<{1,1,1,?}>; // A6.2.3 & A8.6.24
// ARMv4T
+ let isCodeGenOnly = 1 in
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]>;
+ Requires<[IsThumb, IsThumb1Only, IsDarwin]>;
}
let isBranch = 1, isTerminator = 1 in {
@@ -361,8 +367,9 @@ let isBranch = 1, isTerminator = 1 in {
// Far jump
let Defs = [LR] in
def tBfar : TIx2<0b11110, 0b11, 1, (outs), (ins brtarget:$target), IIC_Br,
- "bl\t$target\t${:comment} far jump",[]>;
+ "bl\t$target",[]>;
+ let isCodeGenOnly = 1 in
def tBR_JTr : T1JTI<(outs),
(ins tGPR:$target, jtblock_operand:$jt, i32imm:$id),
IIC_Br, "mov\tpc, $target\n\t.align\t2$jt",
@@ -406,11 +413,9 @@ def tSVC : T1pI<(outs), (ins i32imm:$svc), IIC_Br, "svc", "\t$svc", []>,
// A8.6.16 B: Encoding T1
// If Inst{11-8} == 0b1110 then UNDEFINED
-// FIXME: Temporary emitted as raw bytes until this pseudo-op will be added to
-// binutils
let isBarrier = 1, isTerminator = 1 in
def tTRAP : TI<(outs), (ins), IIC_Br,
- ".short 0xdefe ${:comment} trap", [(trap)]>, Encoding16 {
+ "trap", [(trap)]>, Encoding16 {
let Inst{15-12} = 0b1101;
let Inst{11-8} = 0b1110;
}
@@ -420,47 +425,47 @@ def tTRAP : TI<(outs), (ins), IIC_Br,
//
let canFoldAsLoad = 1, isReMaterializable = 1 in
-def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr,
+def tLDR : T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoad_r,
"ldr", "\t$dst, $addr",
[(set tGPR:$dst, (load t_addrmode_s4:$addr))]>,
T1LdSt<0b100>;
-def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoadr,
+def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoad_r,
"ldr", "\t$dst, $addr",
[]>,
T1LdSt4Imm<{1,?,?}>;
-def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr,
+def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoad_bh_r,
"ldrb", "\t$dst, $addr",
[(set tGPR:$dst, (zextloadi8 t_addrmode_s1:$addr))]>,
T1LdSt<0b110>;
-def tLDRBi: T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoadr,
+def tLDRBi: T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoad_bh_r,
"ldrb", "\t$dst, $addr",
[]>,
T1LdSt1Imm<{1,?,?}>;
-def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr,
+def tLDRH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoad_bh_r,
"ldrh", "\t$dst, $addr",
[(set tGPR:$dst, (zextloadi16 t_addrmode_s2:$addr))]>,
T1LdSt<0b101>;
-def tLDRHi: T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoadr,
+def tLDRHi: T1pI2<(outs tGPR:$dst), (ins t_addrmode_s2:$addr), IIC_iLoad_bh_r,
"ldrh", "\t$dst, $addr",
[]>,
T1LdSt2Imm<{1,?,?}>;
let AddedComplexity = 10 in
-def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoadr,
+def tLDRSB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoad_bh_r,
"ldrsb", "\t$dst, $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,
+def tLDRSH : T1pI2<(outs tGPR:$dst), (ins t_addrmode_rr:$addr), IIC_iLoad_bh_r,
"ldrsh", "\t$dst, $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,
+def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoad_i,
"ldr", "\t$dst, $addr",
[(set tGPR:$dst, (load t_addrmode_sp:$addr))]>,
T1LdStSP<{1,?,?}>;
@@ -468,14 +473,14 @@ def tLDRspi : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi,
// Special instruction for restore. It cannot clobber condition register
// when it's expanded by eliminateCallFramePseudoInstr().
let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1 in
-def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoadi,
+def tRestore : T1pIs<(outs tGPR:$dst), (ins t_addrmode_sp:$addr), IIC_iLoad_i,
"ldr", "\t$dst, $addr", []>,
T1LdStSP<{1,?,?}>;
// Load tconstpool
// FIXME: Use ldr.n to work around a Darwin assembler bug.
let canFoldAsLoad = 1, isReMaterializable = 1 in
-def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
+def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoad_i,
"ldr", ".n\t$dst, $addr",
[(set tGPR:$dst, (load (ARMWrapper tconstpool:$addr)))]>,
T1Encoding<{0,1,0,0,1,?}>; // A6.2 & A8.6.59
@@ -483,38 +488,38 @@ def tLDRpci : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
// Special LDR for loads from non-pc-relative constpools.
let canFoldAsLoad = 1, mayLoad = 1, neverHasSideEffects = 1,
isReMaterializable = 1 in
-def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoadi,
+def tLDRcp : T1pIs<(outs tGPR:$dst), (ins i32imm:$addr), IIC_iLoad_i,
"ldr", "\t$dst, $addr", []>,
T1LdStSP<{1,?,?}>;
-def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer,
+def tSTR : T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStore_r,
"str", "\t$src, $addr",
[(store tGPR:$src, t_addrmode_s4:$addr)]>,
T1LdSt<0b000>;
-def tSTRi: T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStorer,
+def tSTRi: T1pI4<(outs), (ins tGPR:$src, t_addrmode_s4:$addr), IIC_iStore_r,
"str", "\t$src, $addr",
[]>,
T1LdSt4Imm<{0,?,?}>;
-def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer,
+def tSTRB : T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStore_bh_r,
"strb", "\t$src, $addr",
[(truncstorei8 tGPR:$src, t_addrmode_s1:$addr)]>,
T1LdSt<0b010>;
-def tSTRBi: T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStorer,
+def tSTRBi: T1pI1<(outs), (ins tGPR:$src, t_addrmode_s1:$addr), IIC_iStore_bh_r,
"strb", "\t$src, $addr",
[]>,
T1LdSt1Imm<{0,?,?}>;
-def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer,
+def tSTRH : T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStore_bh_r,
"strh", "\t$src, $addr",
[(truncstorei16 tGPR:$src, t_addrmode_s2:$addr)]>,
T1LdSt<0b001>;
-def tSTRHi: T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStorer,
+def tSTRHi: T1pI2<(outs), (ins tGPR:$src, t_addrmode_s2:$addr), IIC_iStore_bh_r,
"strh", "\t$src, $addr",
[]>,
T1LdSt2Imm<{0,?,?}>;
-def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei,
+def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStore_i,
"str", "\t$src, $addr",
[(store tGPR:$src, t_addrmode_sp:$addr)]>,
T1LdStSP<{0,?,?}>;
@@ -522,7 +527,7 @@ def tSTRspi : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei,
let mayStore = 1, neverHasSideEffects = 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,
+def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStore_i,
"str", "\t$src, $addr", []>,
T1LdStSP<{0,?,?}>;
}
@@ -531,37 +536,71 @@ def tSpill : T1pIs<(outs), (ins tGPR:$src, t_addrmode_sp:$addr), IIC_iStorei,
// Load / store multiple Instructions.
//
-// These requires base address to be written back or one of the loaded regs.
-let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1 in {
+multiclass thumb_ldst_mult<string asm, InstrItinClass itin,
+ InstrItinClass itin_upd, bits<6> T1Enc,
+ bit L_bit> {
+ def ia :
+ T1I<(outs), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
+ itin, !strconcat(asm, "${p}\t$Rn, $regs"), []>,
+ T1Encoding<T1Enc>;
+ def ia_UPD :
+ T1It<(outs GPR:$wb), (ins GPR:$Rn, pred:$p, reglist:$regs, variable_ops),
+ itin_upd, !strconcat(asm, "${p}\t$Rn!, $regs"), "$Rn = $wb", []>,
+ T1Encoding<T1Enc>;
+}
+
+/* TODO: Uncommented, this causes a decoding conflict.
+let neverHasSideEffects = 1 in {
+
+let mayLoad = 1, hasExtraDefRegAllocReq = 1 in
+defm tLDM : thumb_ldst_mult<"ldm", IIC_iLoad_m, IIC_iLoad_mu,
+ {1,1,0,0,1,?}, 1>;
+
+let mayStore = 1, hasExtraSrcRegAllocReq = 1 in
+defm tSTM : thumb_ldst_mult<"stm", IIC_iStore_m, IIC_iStore_mu,
+ {1,1,0,0,0,?}, 0>;
+
+} // neverHasSideEffects
+*/
+
+// These require base address to be written back or one of the loaded regs.
+let mayLoad = 1, neverHasSideEffects = 1, hasExtraDefRegAllocReq = 1,
+ isCodeGenOnly = 1 in {
def tLDM : T1I<(outs),
- (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops),
- IIC_iLoadm,
- "ldm${addr:submode}${p}\t$addr, $dsts", []>,
+ (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, reglist:$dsts,
+ variable_ops),
+ IIC_iLoad_m,
+ "ldm${amode}${p}\t$Rn, $dsts", []>,
T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53
def tLDM_UPD : T1It<(outs tGPR:$wb),
- (ins addrmode4:$addr, pred:$p, reglist:$dsts, variable_ops),
- IIC_iLoadm,
- "ldm${addr:submode}${p}\t$addr!, $dsts",
- "$addr.addr = $wb", []>,
+ (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, reglist:$dsts,
+ variable_ops),
+ IIC_iLoad_m,
+ "ldm${amode}${p}\t$Rn!, $dsts",
+ "$Rn = $wb", []>,
T1Encoding<{1,1,0,0,1,?}>; // A6.2 & A8.6.53
} // mayLoad, neverHasSideEffects = 1, hasExtraDefRegAllocReq
-let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in
+let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1,
+ isCodeGenOnly = 1 in
def tSTM_UPD : T1It<(outs tGPR:$wb),
- (ins addrmode4:$addr, pred:$p, reglist:$srcs, variable_ops),
- IIC_iStorem,
- "stm${addr:submode}${p}\t$addr!, $srcs",
- "$addr.addr = $wb", []>,
+ (ins GPR:$Rn, ldstm_mode:$amode, pred:$p, reglist:$srcs,
+ variable_ops),
+ IIC_iStore_mu,
+ "stm${amode}${p}\t$Rn!, $srcs",
+ "$Rn = $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:$dsts, variable_ops), IIC_Br,
+def tPOP : T1I<(outs), (ins pred:$p, reglist:$dsts, variable_ops),
+ IIC_iPop,
"pop${p}\t$dsts", []>,
T1Misc<{1,1,0,?,?,?,?}>;
let mayStore = 1, Uses = [SP], Defs = [SP], hasExtraSrcRegAllocReq = 1 in
-def tPUSH : T1I<(outs), (ins pred:$p, reglist:$srcs, variable_ops), IIC_Br,
+def tPUSH : T1I<(outs), (ins pred:$p, reglist:$srcs, variable_ops),
+ IIC_iStore_m,
"push${p}\t$srcs", []>,
T1Misc<{0,1,0,?,?,?,?}>;
@@ -601,7 +640,7 @@ def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALUr,
// And register
let isCommutable = 1 in
-def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
+def tAND : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iBITr,
"and", "\t$dst, $rhs",
[(set tGPR:$dst, (and tGPR:$lhs, tGPR:$rhs))]>,
T1DataProcessing<0b0000>;
@@ -619,13 +658,13 @@ def tASRrr : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMOVsr,
T1DataProcessing<0b0100>;
// BIC register
-def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
+def tBIC : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iBITr,
"bic", "\t$dst, $rhs",
[(set tGPR:$dst, (and tGPR:$lhs, (not tGPR:$rhs)))]>,
T1DataProcessing<0b1110>;
// CMN register
-let Defs = [CPSR] in {
+let isCompare = 1, Defs = [CPSR] in {
//FIXME: Disable CMN, as CCodes are backwards from compare expectations
// Compare-to-zero still works out, just not the relationals
//def tCMN : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
@@ -639,7 +678,7 @@ def tCMNz : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
}
// CMP immediate
-let Defs = [CPSR] in {
+let isCompare = 1, Defs = [CPSR] in {
def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi,
"cmp", "\t$lhs, $rhs",
[(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>,
@@ -651,7 +690,7 @@ def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iCMPi,
}
// CMP register
-let Defs = [CPSR] in {
+let isCompare = 1, Defs = [CPSR] in {
def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
"cmp", "\t$lhs, $rhs",
[(ARMcmp tGPR:$lhs, tGPR:$rhs)]>,
@@ -672,7 +711,7 @@ def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iCMPr,
// XOR register
let isCommutable = 1 in
-def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
+def tEOR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iBITr,
"eor", "\t$dst, $rhs",
[(set tGPR:$dst, (xor tGPR:$lhs, tGPR:$rhs))]>,
T1DataProcessing<0b0001>;
@@ -741,14 +780,14 @@ def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMUL32,
T1DataProcessing<0b1101>;
// move inverse register
-def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMOVr,
+def tMVN : T1sI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iMVNr,
"mvn", "\t$dst, $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,
+def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iBITr,
"orr", "\t$dst, $rhs",
[(set tGPR:$dst, (or tGPR:$lhs, tGPR:$rhs))]>,
T1DataProcessing<0b1100>;
@@ -757,7 +796,7 @@ def tORR : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALUr,
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<[IsThumb, IsThumb1Only, HasV6]>,
T1Misc<{1,0,1,0,0,0,?}>;
def tREV16 : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
@@ -767,7 +806,7 @@ 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<[IsThumb, IsThumb1Only, HasV6]>,
T1Misc<{1,0,1,0,0,1,?}>;
def tREVSH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
@@ -776,7 +815,7 @@ 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<[IsThumb, IsThumb1Only, HasV6]>,
T1Misc<{1,0,1,0,1,1,?}>;
// rotate right register
@@ -821,19 +860,19 @@ 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<[IsThumb, 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<[IsThumb, 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,
+let isCompare = 1, isCommutable = 1, Defs = [CPSR] in
+def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iTSTr,
"tst", "\t$lhs, $rhs",
[(ARMcmpZ (and tGPR:$lhs, tGPR:$rhs), 0)]>,
T1DataProcessing<0b1000>;
@@ -842,14 +881,14 @@ def tTST : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iCMPr,
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<[IsThumb, 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<[IsThumb, IsThumb1Only, HasV6]>,
T1Misc<{0,0,1,0,1,0,?}>;
@@ -858,7 +897,7 @@ def tUXTH : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iUNAr,
let usesCustomInserter = 1 in // Expanded after instruction selection.
def tMOVCCr_pseudo :
PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc),
- NoItinerary, "${:comment} tMOVCCr $cc",
+ NoItinerary, "",
[/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>;
@@ -913,30 +952,18 @@ let isCall = 1,
// $val is a scratch register for our use.
let Defs =
[ R0, R1, R2, R3, R4, R5, R6, R7, R12 ], hasSideEffects = 1,
- isBarrier = 1 in {
+ isBarrier = 1, isCodeGenOnly = 1 in {
def tInt_eh_sjlj_setjmp : ThumbXI<(outs),(ins tGPR:$src, tGPR:$val),
- AddrModeNone, SizeSpecial, NoItinerary,
- "mov\t$val, pc\t${:comment} begin eh.setjmp\n\t"
- "adds\t$val, #7\n\t"
- "str\t$val, [$src, #4]\n\t"
- "movs\tr0, #0\n\t"
- "b\t1f\n\t"
- "movs\tr0, #1\t${:comment} end eh.setjmp\n\t"
- "1:", "",
+ AddrModeNone, SizeSpecial, NoItinerary, "", "",
[(set R0, (ARMeh_sjlj_setjmp tGPR:$src, tGPR:$val))]>;
}
// FIXME: Non-Darwin version(s)
-let isBarrier = 1, hasSideEffects = 1, isTerminator = 1,
+let isBarrier = 1, hasSideEffects = 1, isTerminator = 1, isCodeGenOnly = 1,
Defs = [ R7, LR, SP ] in {
def tInt_eh_sjlj_longjmp : XI<(outs), (ins GPR:$src, GPR:$scratch),
AddrModeNone, SizeSpecial, IndexModeNone,
- Pseudo, NoItinerary,
- "ldr\t$scratch, [$src, #8]\n\t"
- "mov\tsp, $scratch\n\t"
- "ldr\t$scratch, [$src, #4]\n\t"
- "ldr\tr7, [$src]\n\t"
- "bx\t$scratch", "",
+ Pseudo, NoItinerary, "", "",
[(ARMeh_sjlj_longjmp GPR:$src, GPR:$scratch)]>,
Requires<[IsThumb, IsDarwin]>;
}
@@ -999,10 +1026,10 @@ def : T1Pat<(extloadi16 t_addrmode_s2:$addr), (tLDRH t_addrmode_s2:$addr)>;
// ldr{b|h} + sxt{b|h} instead.
def : T1Pat<(sextloadi8 t_addrmode_s1:$addr),
(tSXTB (tLDRB t_addrmode_s1:$addr))>,
- Requires<[IsThumb1Only, HasV6]>;
+ Requires<[IsThumb, IsThumb1Only, HasV6]>;
def : T1Pat<(sextloadi16 t_addrmode_s2:$addr),
(tSXTH (tLDRH t_addrmode_s2:$addr))>,
- Requires<[IsThumb1Only, HasV6]>;
+ Requires<[IsThumb, IsThumb1Only, HasV6]>;
def : T1Pat<(sextloadi8 t_addrmode_s1:$addr),
(tASRri (tLSLri (tLDRB t_addrmode_s1:$addr), 24), 24)>;
@@ -1024,8 +1051,7 @@ def : T1Pat<(i32 imm0_255_comp:$src),
// scheduling.
let isReMaterializable = 1 in
def tLDRpci_pic : PseudoInst<(outs GPR:$dst), (ins i32imm:$addr, pclabel:$cp),
- NoItinerary,
- "${:comment} ldr.n\t$dst, $addr\n$cp:\n\tadd\t$dst, pc",
+ NoItinerary, "",
[(set GPR:$dst, (ARMpic_add (load (ARMWrapper tconstpool:$addr)),
imm:$cp))]>,
- Requires<[IsThumb1Only]>;
+ Requires<[IsThumb, IsThumb1Only]>;