From 4822bce4aa395e3e96215e18f5c926c78d4a0e64 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 30 Aug 2010 01:47:35 +0000 Subject: Create Thumb2sI_cpsr and T2sI_cpsr. These new classes indicate that CPSR is the optional modified register (instead of reg0). Along with r112461 it will make sure that the optional define of CPSR is marked as "def" and will thus mark the instructions using these classes (t2ANDS*) as setting the 's' flag. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112462 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrFormats.td | 27 ++++++++++++++++--- lib/Target/ARM/ARMInstrThumb2.td | 55 +++++++++++++++++++++++++++++++++------ 2 files changed, 71 insertions(+), 11 deletions(-) (limited to 'lib/Target') diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 12bbde4523..1d48c889f8 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -261,9 +261,9 @@ class InoP Predicates = [IsARM]; } -// Same as I except it can optionally modify CPSR. Note it's modeled as -// an input operand since by default it's a zero register. It will -// become an implicit def once it's "flipped". +// Same as I except it can optionally modify CPSR. Note it's modeled as an input +// operand since by default it's a zero register. It will become an implicit def +// once it's "flipped". class sI Predicates = [IsThumb2]; } +// Same as Thumb2sI except it does modify CPSR. Note it's modeled as an input +// operand since by default it's a zero register. It will become an implicit def +// once it's "flipped". +// FIXME: This uses unified syntax so {s} comes before {p}. We should make it +// more consistent. +class Thumb2sI_cpsr pattern> + : InstARM { + let OutOperandList = oops; + let InOperandList = !con(iops, (ins pred:$p, s_cc_out:$s)); + let AsmString = !strconcat(opc, !strconcat("${s}${p}", asm)); + let Pattern = pattern; + list Predicates = [IsThumb2]; +} + // Special cases class Thumb2XI pattern> : Thumb2sI; +class T2sI_cpsr pattern> + : Thumb2sI_cpsr; + class T2XI pattern> : Thumb2XI; diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 7d2b076c20..df58a1e640 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -214,7 +214,7 @@ multiclass T2I_un_irs opcod, string opc, PatFrag opnode, /// binary operation that produces a value. These are predicable and can be /// changed to modify CPSR. multiclass T2I_bin_irs opcod, string opc, PatFrag opnode, - bit Commutable = 0, string wide = "", bit SBit = 0> { + bit Commutable = 0, string wide = ""> { // shifted imm def ri : T2sI<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_imm:$rhs), IIC_iALUi, opc, "\t$dst, $lhs, $rhs", @@ -222,7 +222,7 @@ multiclass T2I_bin_irs opcod, string opc, PatFrag opnode, let Inst{31-27} = 0b11110; let Inst{25} = 0; let Inst{24-21} = opcod; - let Inst{20} = SBit; // The S bit. + let Inst{20} = ?; // The S bit. let Inst{15} = 0; } // register @@ -233,7 +233,7 @@ multiclass T2I_bin_irs opcod, string opc, PatFrag opnode, let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = opcod; - let Inst{20} = SBit; // The S bit. + let Inst{20} = ?; // The S bit. let Inst{14-12} = 0b000; // imm3 let Inst{7-6} = 0b00; // imm2 let Inst{5-4} = 0b00; // type @@ -245,7 +245,46 @@ multiclass T2I_bin_irs opcod, string opc, PatFrag opnode, let Inst{31-27} = 0b11101; let Inst{26-25} = 0b01; let Inst{24-21} = opcod; - let Inst{20} = SBit; // The S bit. + let Inst{20} = ?; // The S bit. + } +} + +/// T2I_bin_cpsr_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 modify +/// CPSR. +multiclass T2I_bin_cpsr_irs opcod, string opc, PatFrag opnode, + bit Commutable = 0, string wide = ""> { + // shifted imm + def ri : T2sI_cpsr<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_imm:$rhs), + IIC_iALUi, opc, "\t$dst, $lhs, $rhs", + [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_imm:$rhs))]> { + let Inst{31-27} = 0b11110; + let Inst{25} = 0; + let Inst{24-21} = opcod; + let Inst{20} = 1; // The S bit. + let Inst{15} = 0; + } + // register + def rr : T2sI_cpsr<(outs rGPR:$dst), (ins rGPR:$lhs, rGPR:$rhs), + IIC_iALUr, opc, !strconcat(wide, "\t$dst, $lhs, $rhs"), + [(set rGPR:$dst, (opnode rGPR:$lhs, rGPR:$rhs))]> { + let isCommutable = Commutable; + let Inst{31-27} = 0b11101; + let Inst{26-25} = 0b01; + let Inst{24-21} = opcod; + let Inst{20} = 1; // The S bit. + let Inst{14-12} = 0b000; // imm3 + let Inst{7-6} = 0b00; // imm2 + let Inst{5-4} = 0b00; // type + } + // shifted register + def rs : T2sI_cpsr<(outs rGPR:$dst), (ins rGPR:$lhs, t2_so_reg:$rhs), + IIC_iALUsi, opc, !strconcat(wide, "\t$dst, $lhs, $rhs"), + [(set rGPR:$dst, (opnode rGPR:$lhs, t2_so_reg:$rhs))]> { + let Inst{31-27} = 0b11101; + let Inst{26-25} = 0b01; + let Inst{24-21} = opcod; + let Inst{20} = 1; // The S bit. } } @@ -253,13 +292,13 @@ multiclass T2I_bin_irs opcod, string opc, PatFrag opnode, // the ".w" prefix to indicate that they are wide. multiclass T2I_bin_w_irs opcod, string opc, PatFrag opnode, bit Commutable = 0> : - T2I_bin_irs; + T2I_bin_irs; /// T2I_bin_sw_irs - Same as T2I_bin_w_irs except these operations set // the 'S' bit. multiclass T2I_bin_sw_irs opcod, string opc, PatFrag opnode, bit Commutable = 0> : - T2I_bin_irs; + T2I_bin_cpsr_irs; /// T2I_rbin_is - Same as T2I_bin_irs except the order of operands are /// reversed. The 'rr' form is only defined for the disassembler; for codegen @@ -1637,7 +1676,7 @@ defm t2EOR : T2I_bin_w_irs<0b0100, "eor", defm t2BIC : T2I_bin_w_irs<0b0001, "bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>; -let Defs = [CPSR] in +//let Defs = [CPSR] in defm t2ANDS : T2I_bin_sw_irs<0b0000, "and", BinOpFrag<(ARMand node:$LHS, node:$RHS)>, 1>; @@ -1682,7 +1721,7 @@ def t2BFI : T2I<(outs rGPR:$dst), } defm t2ORN : T2I_bin_irs<0b0011, "orn", BinOpFrag<(or node:$LHS, - (not node:$RHS))>, 0, "", ?>; + (not node:$RHS))>, 0, "">; // Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version let AddedComplexity = 1 in -- cgit v1.2.3