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";
}
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",
string EncoderMethod = "getT2SORegOpValue";
let MIOperandInfo = (ops rGPR, 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()), MVT::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()), MVT::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 Pred_t2_so_imm(N); }]> {
string EncoderMethod = "getT2SOImmOpValue";
}
// t2_so_imm_not - Match an immediate that is a complement
Evan Cheng
committed
// 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(-((uint32_t)N->getZExtValue())) != -1;
}], t2_so_imm_neg_XFORM>;
Jim Grosbach
committed
// 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);
}]>;
Jim Grosbach
committed
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;
}]>;
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), [{
return (uint32_t)(-N->getZExtValue()) < 4096;
}], imm_neg_XFORM>;
def imm0_255_neg : PatLeaf<(i32 imm), [{
return (uint32_t)(-N->getZExtValue()) < 255;
def imm0_255_not : PatLeaf<(i32 imm), [{
return (uint32_t)(~N->getZExtValue()) < 255;
}], imm_comp_XFORM>;
// Define Thumb2 specific addressing modes.
// t2addrmode_imm12 := reg + imm12
def t2addrmode_imm12 : Operand<i32>,
ComplexPattern<i32, 2, "SelectT2AddrModeImm12", []> {
let PrintMethod = "printAddrModeImm12Operand";
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}
// t2addrmode_imm8 := reg +/- imm8
def t2addrmode_imm8 : Operand<i32>,
ComplexPattern<i32, 2, "SelectT2AddrModeImm8", []> {
let PrintMethod = "printT2AddrModeImm8Operand";
let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
}
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";
}
def t2addrmode_so_reg : Operand<i32>,
ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
let PrintMethod = "printT2AddrModeSoRegOperand";
let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
//===----------------------------------------------------------------------===//
class T2TwoRegShiftedImm<dag oops, dag iops, InstrItinClass itin,
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
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...