Newer
Older
Evan Cheng
committed
// Short range conditional branch. Looks awesome for loops. Need to figure
// out how to use this one.
// 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. :(
def t2MOVCCr : T2I<(outs GPR:$dst), (ins GPR:$false, GPR:$true),
"mov", " $dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, GPR:$true, imm:$cc, CCR:$ccr))*/]>,
RegConstraint<"$false = $dst">;
def t2MOVCCs : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_reg:$true),
"mov", " $dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_reg:$true, imm:$cc, CCR:$ccr))*/]>,
RegConstraint<"$false = $dst">;
def t2MOVCCi : T2I<(outs GPR:$dst), (ins GPR:$false, t2_so_imm:$true),
"mov", " $dst, $true",
[/*(set GPR:$dst, (ARMcmov GPR:$false, t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
RegConstraint<"$false = $dst">;
Evan Cheng
committed
David Goodwin
committed
//===----------------------------------------------------------------------===//
// TLS Instructions
//
// __aeabi_read_tp preserves the registers r1-r3.
let isCall = 1,
Defs = [R0, R12, LR, CPSR] in {
def t2TPsoft : T2XI<(outs), (ins),
"bl __aeabi_read_tp",
[(set R0, ARMthread_pointer)]>;
}
//===----------------------------------------------------------------------===//
// 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?
let isReturn = 1, isTerminator = 1, mayLoad = 1 in
def t2LDM_RET : T2XI<(outs),
(ins addrmode4:$addr, pred:$p, reglist:$dst1, variable_ops),
"ldm${addr:submode}${p} $addr, $dst1",
[]>;
David Goodwin
committed
// On non-Darwin platforms R9 is callee-saved.
Defs = [R0, R1, R2, R3, R12, LR,
D0, D1, D2, D3, D4, D5, D6, D7,
D16, D17, D18, D19, D20, D21, D22, D23,
D24, D25, D26, D27, D28, D29, D31, D31, CPSR] in {
def t2BL : T2XI<(outs), (ins i32imm:$func, variable_ops),
"bl ${func:call}",
[(ARMcall tglobaladdr:$func)]>, Requires<[IsNotDarwin]>;
def t2BLX : T2XI<(outs), (ins GPR:$func, variable_ops),
"blx $func",
[(ARMcall GPR:$func)]>, Requires<[IsNotDarwin]>;
}
David Goodwin
committed
// On Darwin R9 is call-clobbered.
let isCall = 1,
Defs = [R0, R1, R2, R3, R9, R12, LR,
D0, D1, D2, D3, D4, D5, D6, D7, CPSR] in {
def t2BLr9 : T2XI<(outs), (ins i32imm:$func, variable_ops),
"bl ${func:call}",
[(ARMcall tglobaladdr:$func)]>, Requires<[IsDarwin]>;
def t2BLXr9 : T2XI<(outs), (ins GPR:$func, variable_ops),
"blx $func",
[(ARMcall GPR:$func)]>, Requires<[IsDarwin]>;
}
David Goodwin
committed
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
let isPredicable = 1 in
def t2B : T2XI<(outs), (ins brtarget:$target),
"b $target",
[(br bb:$target)]>;
let isNotDuplicable = 1, isIndirectBranch = 1 in {
def t2BR_JTr : T2JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id),
"mov pc, $target \n\t.align\t2\n$jt",
[(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>;
def t2BR_JTm :
T2JTI<(outs),
(ins t2addrmode_so_reg:$target, jtblock_operand:$jt, i32imm:$id),
"ldr pc, $target \n\t.align\t2\n$jt",
[(ARMbrjt (i32 (load t2addrmode_so_reg:$target)), tjumptable:$jt,
imm:$id)]>;
def t2BR_JTadd :
T2JTI<(outs),
(ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id),
"add pc, $target, $idx \n\t.align\t2\n$jt",
[(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, imm:$id)]>;
} // isNotDuplicate, 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
def t2Bcc : T2I<(outs), (ins brtarget:$target),
"b", " $target",
[/*(ARMbrcond bb:$target, imm:$cc)*/]>;
Evan Cheng
committed
// IT block
def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
AddrModeNone, Size2Bytes,
"it$mask $cc", "", []>;
Evan Cheng
committed
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
//
def : T2Pat<(ARMWrapper tglobaladdr :$dst), (t2LEApcrel tglobaladdr :$dst)>;
def : T2Pat<(ARMWrapper tconstpool :$dst), (t2LEApcrel tconstpool :$dst)>;
def : T2Pat<(ARMWrapperJT tjumptable:$dst, imm:$id),
(t2LEApcrelJT tjumptable:$dst, imm:$id)>;
Evan Cheng
committed
// Large immediate handling.
def : T2Pat<(i32 imm:$src),
(t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;