Skip to content
ARMInstrThumb2.td 110 KiB
Newer Older
//===- ARMInstrThumb2.td - Thumb2 support for ARM -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file describes the Thumb2 instruction set.
//
//===----------------------------------------------------------------------===//
// IT block predicate field
def it_pred : Operand<i32> {
  let PrintMethod = "printMandatoryPredicateOperand";
}

// IT block condition mask
def it_mask : Operand<i32> {
  let PrintMethod = "printThumbITMask";
}

// Table branch address
def tb_addrmode : Operand<i32> {
  let PrintMethod = "printTBAddrMode";
}

// Shifted operands. No register controlled shifts for Thumb2.
// Note: We do not support rrx shifted operands yet.
def t2_so_reg : Operand<i32>,    // reg imm
Evan Cheng's avatar
Evan Cheng committed
                ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
                               [shl,srl,sra,rotr]> {
  string EncoderMethod = "getT2SORegOpValue";
Evan Cheng's avatar
Evan Cheng committed
  let PrintMethod = "printT2SOOperand";
  let MIOperandInfo = (ops rGPR, i32imm);
// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
  return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32);
// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
  return CurDAG->getTargetConstant(-((int)N->getZExtValue()), MVT::i32);
}]>;

// t2_so_imm - Match a 32-bit immediate operand, which is an
// 8-bit immediate rotated by an arbitrary number of bits, or an 8-bit
// immediate splatted into multiple bytes of the word. t2_so_imm values are
// represented in the imm field in the same 12-bit form that they are encoded
Jim Grosbach's avatar
Jim Grosbach committed
// into t2_so_imm instructions: the 8-bit immediate is the least significant
// bits [bits 0-7], the 4-bit shift/splat amount is the next 4 bits [bits 8-11].
def t2_so_imm : Operand<i32>, PatLeaf<(imm), [{ return Pred_t2_so_imm(N); }]> {
  string EncoderMethod = "getT2SOImmOpValue";
}
Jim Grosbach's avatar
Jim Grosbach committed
// t2_so_imm_not - Match an immediate that is a complement
// of a t2_so_imm.
def t2_so_imm_not : Operand<i32>,
                    PatLeaf<(imm), [{
  return ARM_AM::getT2SOImmVal(~((uint32_t)N->getZExtValue())) != -1;
}], t2_so_imm_not_XFORM>;

// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
def t2_so_imm_neg : Operand<i32>,
                    PatLeaf<(imm), [{
  return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1;
// Break t2_so_imm's up into two pieces.  This handles immediates with up to 16
// bits set in them.  This uses t2_so_imm2part to match and t2_so_imm2part_[12]
// to get the first/second pieces.
def t2_so_imm2part : Operand<i32>,
                  PatLeaf<(imm), [{
      return ARM_AM::isT2SOImmTwoPartVal((unsigned)N->getZExtValue());
    }]> {
}

def t2_so_imm2part_1 : SDNodeXForm<imm, [{
  unsigned V = ARM_AM::getT2SOImmTwoPartFirst((unsigned)N->getZExtValue());
  return CurDAG->getTargetConstant(V, MVT::i32);
}]>;

def t2_so_imm2part_2 : SDNodeXForm<imm, [{
  unsigned V = ARM_AM::getT2SOImmTwoPartSecond((unsigned)N->getZExtValue());
  return CurDAG->getTargetConstant(V, MVT::i32);
}]>;

def t2_so_neg_imm2part : Operand<i32>, PatLeaf<(imm), [{
      return ARM_AM::isT2SOImmTwoPartVal(-(int)N->getZExtValue());
    }]> {
}

def t2_so_neg_imm2part_1 : SDNodeXForm<imm, [{
  unsigned V = ARM_AM::getT2SOImmTwoPartFirst(-(int)N->getZExtValue());
  return CurDAG->getTargetConstant(V, MVT::i32);
}]>;

def t2_so_neg_imm2part_2 : SDNodeXForm<imm, [{
  unsigned V = ARM_AM::getT2SOImmTwoPartSecond(-(int)N->getZExtValue());
  return CurDAG->getTargetConstant(V, MVT::i32);
}]>;

/// imm1_31 predicate - True if the 32-bit immediate is in the range [1,31].
def imm1_31 : PatLeaf<(i32 imm), [{
  return (int32_t)N->getZExtValue() >= 1 && (int32_t)N->getZExtValue() < 32;
}]>;

/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
def imm0_4095 : Operand<i32>,
                PatLeaf<(i32 imm), [{
  return (uint32_t)N->getZExtValue() < 4096;
}]>;
Jim Grosbach's avatar
Jim Grosbach committed
def imm0_4095_neg : PatLeaf<(i32 imm), [{
 return (uint32_t)(-N->getZExtValue()) < 4096;
}], imm_neg_XFORM>;
def imm0_255_neg : PatLeaf<(i32 imm), [{
  return (uint32_t)(-N->getZExtValue()) < 255;
Jim Grosbach's avatar
Jim Grosbach committed
}], imm_neg_XFORM>;
def imm0_255_not : PatLeaf<(i32 imm), [{
  return (uint32_t)(~N->getZExtValue()) < 255;
}], imm_comp_XFORM>;

Evan Cheng's avatar
Evan Cheng committed
// Define Thumb2 specific addressing modes.

// t2addrmode_imm12  := reg + imm12
def t2addrmode_imm12 : Operand<i32>,
                       ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
  let PrintMethod = "printAddrModeImm12Operand";
Evan Cheng's avatar
Evan Cheng committed
  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}

// t2addrmode_imm8  := reg +/- imm8
Evan Cheng's avatar
Evan Cheng committed
def t2addrmode_imm8 : Operand<i32>,
                      ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
  let PrintMethod = "printT2AddrModeImm8Operand";
  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}

Evan Cheng's avatar
Evan Cheng committed
def t2am_imm8_offset : Operand<i32>,
                       ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset",
                                      [], [SDNPWantRoot]> {
  let PrintMethod = "printT2AddrModeImm8OffsetOperand";
}

// t2addrmode_imm8s4  := reg +/- (imm8 << 2)
def t2addrmode_imm8s4 : Operand<i32> {
  let PrintMethod = "printT2AddrModeImm8s4Operand";
  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}

def t2am_imm8s4_offset : Operand<i32> {
  let PrintMethod = "printT2AddrModeImm8s4OffsetOperand";
}

Evan Cheng's avatar
Evan Cheng committed
// t2addrmode_so_reg  := reg + (reg << imm2)
Evan Cheng's avatar
Evan Cheng committed
def t2addrmode_so_reg : Operand<i32>,
                        ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
  let PrintMethod = "printT2AddrModeSoRegOperand";
  let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
//===----------------------------------------------------------------------===//
Evan Cheng's avatar
Evan Cheng committed
// Multiclass helpers...
class T2TwoRegShiftedImm<dag oops, dag iops, InstrItinClass itin,
           string opc, string asm, list<dag> pattern>
  : T2sI<oops, iops, itin, opc, asm, pattern> {
  bits<4> Rd;
  bits<4> Rn;
  bits<12> imm;
  
  let Inst{11-8}  = Rd{3-0};
  let Inst{19-16} = Rn{3-0};
  let Inst{26}    = imm{11};
  let Inst{14-12} = imm{10-8};
  let Inst{7-0}   = imm{7-0};
}

class T2ThreeReg<dag oops, dag iops, InstrItinClass itin,
           string opc, string asm, list<dag> pattern>
  : T2sI<oops, iops, itin, opc, asm, pattern> { 
  bits<4> Rd;
  bits<4> Rn;
  bits<4> Rm;
     
  let Inst{11-8}  = Rd{3-0};
  let Inst{19-16} = Rn{3-0};
  let Inst{3-0}   = Rm{3-0};
}

class T2TwoRegShiftedReg<dag oops, dag iops, InstrItinClass itin,
           string opc, string asm, list<dag> pattern>
Loading
Loading full blame...