Skip to content
ARMInstrThumb2.td 44.4 KiB
Newer Older
// 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",
                    []>;

// 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]>;
}
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]>;
}
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
let isPredicable = 1 in
def t2B   : T2XI<(outs), (ins brtarget:$target),
let isNotDuplicable = 1, isIndirectBranch = 1 in
def t2BR_JT :
    T2JTI<(outs),
          (ins GPR:$base, GPR:$idx, jt2block_operand:$jt, i32imm:$id),
          "add.w pc, $base, $idx, lsl #2\n$jt",
          [(ARMbr2jt GPR:$base, GPR:$idx, tjumptable:$jt, imm:$id)]>;
} // 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", ".w $target",
                [/*(ARMbrcond bb:$target, imm:$cc)*/]>;

// IT block
def t2IT : Thumb2XI<(outs), (ins it_pred:$cc, it_mask:$mask),
                    AddrModeNone, Size2Bytes,
                    "it$mask $cc", "", []>;

//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
//

Evan Cheng's avatar
Evan Cheng committed
// ConstantPool, GlobalAddress, and JumpTable
Evan Cheng's avatar
Evan Cheng committed
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's avatar
Evan Cheng committed
def : T2Pat<(i32 imm:$src),
            (t2MOVTi16 (t2MOVi16 (t2_lo16 imm:$src)), (t2_hi16 imm:$src))>;