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 = "printPredicateOperand";
}
// IT block condition mask
def it_mask : Operand<i32> {
let PrintMethod = "printThumbITMask";
}
Evan Cheng
committed
// 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
ComplexPattern<i32, 2, "SelectT2ShifterOperandReg",
let MIOperandInfo = (ops GPR, i32imm);
}
Evan Cheng
committed
// t2_so_imm_not_XFORM - Return the complement of a t2_so_imm value
def t2_so_imm_not_XFORM : SDNodeXForm<imm, [{
Owen Anderson
committed
return CurDAG->getTargetConstant(~((uint32_t)N->getZExtValue()), EVT::i32);
Evan Cheng
committed
// t2_so_imm_neg_XFORM - Return the negation of a t2_so_imm value
def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
Owen Anderson
committed
return CurDAG->getTargetConstant(-((int)N->getZExtValue()), EVT::i32);
Evan Cheng
committed
}]>;
// 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
// 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 ARM_AM::getT2SOImmVal((uint32_t)N->getZExtValue()) != -1;
}]>;
Evan Cheng
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>;
Evan Cheng
committed
// 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(-((int)N->getZExtValue())) != -1;
}], t2_so_imm_neg_XFORM>;
/// 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;
}]>;
Evan Cheng
committed
/// imm0_4095 predicate - True if the 32-bit immediate is in the range [0.4095].
Evan Cheng
committed
def imm0_4095 : Operand<i32>,
PatLeaf<(i32 imm), [{
Evan Cheng
committed
return (uint32_t)N->getZExtValue() < 4096;
}]>;
def imm0_4095_neg : PatLeaf<(i32 imm), [{
Evan Cheng
committed
return (uint32_t)(-N->getZExtValue()) < 4096;
}], imm_neg_XFORM>;
def imm0_255_neg : PatLeaf<(i32 imm), [{
return (uint32_t)(-N->getZExtValue()) < 255;
}], imm_neg_XFORM>;
Evan Cheng
committed
/// imm0_65535 predicate - True if the 32-bit immediate is in the range
/// [0.65535].
def imm0_65535 : PatLeaf<(i32 imm), [{
return (uint32_t)N->getZExtValue() < 65536;
Evan Cheng
committed
/// Split a 32-bit immediate into two 16 bit parts.
def t2_lo16 : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
Owen Anderson
committed
EVT::i32);
Evan Cheng
committed
}]>;
def t2_hi16 : SDNodeXForm<imm, [{
Owen Anderson
committed
return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() >> 16, EVT::i32);
Evan Cheng
committed
}]>;
def t2_lo16AllZero : PatLeaf<(i32 imm), [{
// Returns true if all low 16-bits are 0.
return (((uint32_t)N->getZExtValue()) & 0xFFFFUL) == 0;
}], t2_hi16>;
// Define Thumb2 specific addressing modes.
// t2addrmode_imm12 := reg + imm12
def t2addrmode_imm12 : Operand<i32>,
ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
let PrintMethod = "printT2AddrModeImm12Operand";
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}
David Goodwin
committed
// t2addrmode_imm8 := reg - imm8
def t2addrmode_imm8 : Operand<i32>,
ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
let PrintMethod = "printT2AddrModeImm8Operand";
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}
def t2am_imm8_offset : Operand<i32>,
ComplexPattern<i32, 1, "SelectT2AddrModeImm8Offset", []>{
let PrintMethod = "printT2AddrModeImm8OffsetOperand";
}
// t2addrmode_imm8s4 := reg +/- (imm8 << 2)
def t2addrmode_imm8s4 : Operand<i32>,
ComplexPattern<i32, 2, "SelectT2AddrModeImm8s4", []> {
let PrintMethod = "printT2AddrModeImm8s4Operand";
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}
def t2addrmode_so_reg : Operand<i32>,
ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
let PrintMethod = "printT2AddrModeSoRegOperand";
let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
}
//===----------------------------------------------------------------------===//
/// T2I_un_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
/// unary operation that produces a value. These are predicable and can be
/// changed to modify CPSR.
multiclass T2I_un_irs<string opc, PatFrag opnode, bit Cheap = 0, bit ReMat = 0>{
// shifted imm
David Goodwin
committed
def i : T2sI<(outs GPR:$dst), (ins t2_so_imm:$src), IIC_iALU,
opc, " $dst, $src",
[(set GPR:$dst, (opnode t2_so_imm:$src))]> {
let isAsCheapAsAMove = Cheap;
let isReMaterializable = ReMat;
}
// register
David Goodwin
committed
def r : T2I<(outs GPR:$dst), (ins GPR:$src), IIC_iALU,
[(set GPR:$dst, (opnode GPR:$src))]>;
// shifted register
David Goodwin
committed
def s : T2I<(outs GPR:$dst), (ins t2_so_reg:$src), IIC_iALU,
[(set GPR:$dst, (opnode t2_so_reg:$src))]>;
}
/// T2I_bin_irs - Defines a set of (op reg, {so_imm|r|so_reg}) patterns for a
// binary operation that produces a value. These are predicable and can be
/// changed to modify CPSR.
David Goodwin
committed
multiclass T2I_bin_irs<string opc, PatFrag opnode,
bit Commutable = 0, string wide =""> {
Evan Cheng
committed
// shifted imm
David Goodwin
committed
def ri : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_imm:$rhs), IIC_iALU,
opc, " $dst, $lhs, $rhs",
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_imm:$rhs))]>;
David Goodwin
committed
def rr : T2sI<(outs GPR:$dst), (ins GPR:$lhs, GPR:$rhs), IIC_iALU,
David Goodwin
committed
opc, !strconcat(wide, " $dst, $lhs, $rhs"),
[(set GPR:$dst, (opnode GPR:$lhs, GPR:$rhs))]> {
let isCommutable = Commutable;
}
Evan Cheng
committed
// shifted register
David Goodwin
committed
def rs : T2sI<(outs GPR:$dst), (ins GPR:$lhs, t2_so_reg:$rhs), IIC_iALU,
David Goodwin
committed
opc, !strconcat(wide, " $dst, $lhs, $rhs"),
[(set GPR:$dst, (opnode GPR:$lhs, t2_so_reg:$rhs))]>;
Evan Cheng
committed
}
David Goodwin
committed
/// T2I_bin_w_irs - Same as T2I_bin_irs except these operations need
// the ".w" prefix to indicate that they are wide.
multiclass T2I_bin_w_irs<string opc, PatFrag opnode, bit Commutable = 0> :
T2I_bin_irs<opc, opnode, Commutable, ".w">;
Evan Cheng
committed
/// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are
Loading
Loading full blame...