//===- ARMInstrThumb.td - Thumb support for ARM ------------*- tablegen -*-===// // // 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 Thumb instruction set. // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // Thumb specific DAG Nodes. // def ARMtcall : SDNode<"ARMISD::tCALL", SDT_ARMcall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag, SDNPVariadic]>; def imm_neg_XFORM : SDNodeXFormgetTargetConstant(-(int)N->getZExtValue(), MVT::i32); }]>; def imm_comp_XFORM : SDNodeXFormgetTargetConstant(~((uint32_t)N->getZExtValue()), MVT::i32); }]>; /// imm0_7 predicate - True if the 32-bit immediate is in the range [0,7]. def imm0_7 : PatLeaf<(i32 imm), [{ return (uint32_t)N->getZExtValue() < 8; }]>; def imm0_7_neg : PatLeaf<(i32 imm), [{ return (uint32_t)-N->getZExtValue() < 8; }], imm_neg_XFORM>; def imm0_255 : PatLeaf<(i32 imm), [{ return (uint32_t)N->getZExtValue() < 256; }]>; def imm0_255_comp : PatLeaf<(i32 imm), [{ return ~((uint32_t)N->getZExtValue()) < 256; }]>; def imm8_255 : PatLeaf<(i32 imm), [{ return (uint32_t)N->getZExtValue() >= 8 && (uint32_t)N->getZExtValue() < 256; }]>; def imm8_255_neg : PatLeaf<(i32 imm), [{ unsigned Val = -N->getZExtValue(); return Val >= 8 && Val < 256; }], imm_neg_XFORM>; // Break imm's up into two pieces: an immediate + a left shift. This uses // thumb_immshifted to match and thumb_immshifted_val and thumb_immshifted_shamt // to get the val/shift pieces. def thumb_immshifted : PatLeaf<(imm), [{ return ARM_AM::isThumbImmShiftedVal((unsigned)N->getZExtValue()); }]>; def thumb_immshifted_val : SDNodeXFormgetZExtValue()); return CurDAG->getTargetConstant(V, MVT::i32); }]>; def thumb_immshifted_shamt : SDNodeXFormgetZExtValue()); return CurDAG->getTargetConstant(V, MVT::i32); }]>; // Scaled 4 immediate. def t_imm_s4 : Operand { let PrintMethod = "printThumbS4ImmOperand"; } // Define Thumb specific addressing modes. def t_brtarget : Operand { let EncoderMethod = "getThumbBRTargetOpValue"; } def t_bltarget : Operand { let EncoderMethod = "getThumbBLTargetOpValue"; } def t_blxtarget : Operand { let EncoderMethod = "getThumbBLXTargetOpValue"; } def MemModeThumbAsmOperand : AsmOperandClass { let Name = "MemModeThumb"; let SuperClasses = []; } // t_addrmode_rr := reg + reg // def t_addrmode_rr : Operand, ComplexPattern { let PrintMethod = "printThumbAddrModeRROperand"; let MIOperandInfo = (ops tGPR:$base, tGPR:$offsreg); } // t_addrmode_s4 := reg + reg // reg + imm5 * 4 // def t_addrmode_s4 : Operand, ComplexPattern { let EncoderMethod = "getAddrModeS4OpValue"; let PrintMethod = "printThumbAddrModeS4Operand"; let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); let ParserMatchClass = MemModeThumbAsmOperand; } // t_addrmode_s2 := reg + reg // reg + imm5 * 2 // def t_addrmode_s2 : Operand, ComplexPattern { let EncoderMethod = "getAddrModeS2OpValue"; let PrintMethod = "printThumbAddrModeS2Operand"; let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); let ParserMatchClass = MemModeThumbAsmOperand; } // t_addrmode_s1 := reg + reg // reg + imm5 // def t_addrmode_s1 : Operand, ComplexPattern { let EncoderMethod = "getAddrModeS1OpValue"; let PrintMethod = "printThumbAddrModeS1Operand"; let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg); let ParserMatchClass = MemModeThumbAsmOperand; } // t_addrmode_sp := sp + imm8 * 4 // def t_addrmode_sp : Operand, ComplexPattern { let EncoderMethod = "getAddrModeThumbSPOpValue"; let PrintMethod = "printThumbAddrModeSPOperand"; let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm); let ParserMatchClass = MemModeThumbAsmOperand; } // t_addrmode_pc :=