"add $dst, pc, $rhs * 4", []>;
// ADD rd, sp, #imm8
-// FIXME: hard code sp?
def tADDrSPi : T1I<(outs tGPR:$dst), (ins GPR:$sp, i32imm:$rhs), IIC_iALU,
"add $dst, $sp, $rhs * 4 @ addrspi", []>;
// ADD sp, sp, #imm7
-// FIXME: hard code sp?
-def tADDspi : T1It<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
+def tADDspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
"add $dst, $rhs * 4", []>;
-// FIXME: Make use of the following?
-// ADD rm, sp, rm
+// SUB sp, sp, #imm7
+def tSUBspi : TIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
+ "sub $dst, $rhs * 4", []>;
+
+// ADD rm, sp
+def tADDrSP : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
+ "add $dst, $rhs", []>;
+
// ADD sp, rm
+def tADDspr : TIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
+ "add $dst, $rhs", []>;
+
+// Pseudo instruction that will expand into a tSUBspi + a copy.
+let usesCustomDAGSchedInserter = 1 in { // Expanded by the scheduler.
+def tSUBspi_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs),
+ NoItinerary, "@ sub $dst, $rhs * 4", []>;
+
+def tADDspr_ : PseudoInst<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs),
+ NoItinerary, "@ add $dst, $rhs", []>;
+
+let Defs = [CPSR] in
+def tANDsp : PseudoInst<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs),
+ NoItinerary, "@ and $dst, $rhs", []>;
+} // usesCustomDAGSchedInserter
//===----------------------------------------------------------------------===//
// Control Flow Instructions.
}
// FIXME: remove when we have a way to marking a MI with these properties.
-let isReturn = 1, isTerminator = 1 in
-def tPOP_RET : T1I<(outs reglist:$dst1, variable_ops), (ins), IIC_Br,
- "pop $dst1", []>;
+let isReturn = 1, isTerminator = 1, mayLoad = 1 in
+def tPOP_RET : T1I<(outs), (ins pred:$p, reglist:$dst1, variable_ops), IIC_Br,
+ "pop${p} $dst1", []>;
let isCall = 1,
Defs = [R0, R1, R2, R3, R12, LR,
"b $target", [(br bb:$target)]>;
// Far jump
+ let Defs = [LR] in
def tBfar : TIx2<(outs), (ins brtarget:$target), IIC_Br,
"bl $target\t@ far jump",[]>;
// Load / store multiple Instructions.
//
-// TODO: A7-44: LDMIA - load multiple
-// TODO: Allow these to be predicated
-
+// These requires base address to be written back or one of the loaded regs.
let mayLoad = 1 in
-def tPOP : T1I<(outs reglist:$dst1, variable_ops), (ins), IIC_Br,
- "pop $dst1", []>;
+def tLDM : T1I<(outs),
+ (ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
+ IIC_iLoad,
+ "ldm${addr:submode}${p} $addr, $dst1", []>;
let mayStore = 1 in
-def tPUSH : T1I<(outs), (ins reglist:$src1, variable_ops), IIC_Br,
- "push $src1", []>;
+def tSTM : T1I<(outs),
+ (ins addrmode4:$addr, pred:$p, reglist:$src1, variable_ops),
+ IIC_iStore,
+ "stm${addr:submode}${p} $addr, $src1", []>;
+
+let mayLoad = 1, Uses = [SP], Defs = [SP] in
+def tPOP : T1I<(outs), (ins pred:$p, reglist:$dst1, variable_ops), IIC_Br,
+ "pop${p} $dst1", []>;
+
+let mayStore = 1, Uses = [SP], Defs = [SP] in
+def tPUSH : T1I<(outs), (ins pred:$p, reglist:$src1, variable_ops), IIC_Br,
+ "push${p} $src1", []>;
//===----------------------------------------------------------------------===//
// Arithmetic Instructions.
[(set tGPR:$dst, (add tGPR:$lhs, tGPR:$rhs))]>;
let neverHasSideEffects = 1 in
-def tADDhirr : T1pIt<(outs tGPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
+def tADDhirr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
"add", " $dst, $rhs @ addhirr", []>;
// And register
def tCMPi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
"cmp", " $lhs, $rhs",
[(ARMcmp tGPR:$lhs, imm0_255:$rhs)]>;
-def tCMPZi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
+def tCMPzi8 : T1pI<(outs), (ins tGPR:$lhs, i32imm:$rhs), IIC_iALU,
"cmp", " $lhs, $rhs",
[(ARMcmpZ tGPR:$lhs, imm0_255:$rhs)]>;
def tCMPr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
"cmp", " $lhs, $rhs",
[(ARMcmp tGPR:$lhs, tGPR:$rhs)]>;
-def tCMPZr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
+def tCMPzr : T1pI<(outs), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
"cmp", " $lhs, $rhs",
[(ARMcmpZ tGPR:$lhs, tGPR:$rhs)]>;
-// TODO: Make use of the followings cmp hi regs
def tCMPhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
"cmp", " $lhs, $rhs", []>;
-def tCMPZhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
+def tCMPzhir : T1pI<(outs), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
"cmp", " $lhs, $rhs", []>;
}
// multiply register
let isCommutable = 1 in
-def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iALU,
+def tMUL : T1sIt<(outs tGPR:$dst), (ins tGPR:$lhs, tGPR:$rhs), IIC_iMPYw,
"mul", " $dst, $rhs",
[(set tGPR:$dst, (mul tGPR:$lhs, tGPR:$rhs))]>;
// TODO: A7-96: STMIA - store multiple.
-def tSUBspi : T1It<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
- "sub $dst, $rhs * 4", []>;
-
// sign-extend byte
def tSXTB : T1pI<(outs tGPR:$dst), (ins tGPR:$src), IIC_iALU,
"sxtb", " $dst, $src",
// Conditional move tMOVCCr - Used to implement the Thumb SELECT_CC DAG operation.
// Expanded by the scheduler into a branch sequence.
-// FIXME: Add actual movcc in IT blocks for Thumb2.
let usesCustomDAGSchedInserter = 1 in // Expanded by the scheduler.
- def tMOVCCr :
- PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc), IIC_iALU,
- "@ tMOVCCr $cc",
- [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>;
+ def tMOVCCr_pseudo :
+ PseudoInst<(outs tGPR:$dst), (ins tGPR:$false, tGPR:$true, pred:$cc),
+ NoItinerary, "@ tMOVCCr $cc",
+ [/*(set tGPR:$dst, (ARMcmov tGPR:$false, tGPR:$true, imm:$cc))*/]>;
+
+
+// 16-bit movcc in IT blocks for Thumb2.
+def tMOVCCr : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
+ "mov", " $dst, $rhs", []>;
+
+def tMOVCCi : T1pIt<(outs GPR:$dst), (ins GPR:$lhs, i32imm:$rhs), IIC_iALU,
+ "mov", " $dst, $rhs", []>;
// tLEApcrel - Load a pc-relative address into a register without offending the
// assembler.
def tLEApcrel : T1I<(outs tGPR:$dst), (ins i32imm:$label), IIC_iALU,
"adr $dst, #$label", []>;
-def tLEApcrelJT : T1I<(outs tGPR:$dst), (ins i32imm:$label, i32imm:$id), IIC_iALU,
- "adr $dst, #${label}_${id:no_hash}", []>;
+def tLEApcrelJT : T1I<(outs tGPR:$dst), (ins i32imm:$label, lane_cst:$id),
+ IIC_iALU, "adr $dst, #${label}_${id}", []>;
//===----------------------------------------------------------------------===//
// TLS Instructions