summaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2010-08-30 01:47:35 +0000
committerBill Wendling <isanbard@gmail.com>2010-08-30 01:47:35 +0000
commit4822bce4aa395e3e96215e18f5c926c78d4a0e64 (patch)
tree8f3bd11b6384938017224264cea606bf7764408c /lib/Target
parent25b141912ce4f5a4b8a0684e870569ece21facde (diff)
downloadllvm-4822bce4aa395e3e96215e18f5c926c78d4a0e64.tar.gz
llvm-4822bce4aa395e3e96215e18f5c926c78d4a0e64.tar.bz2
llvm-4822bce4aa395e3e96215e18f5c926c78d4a0e64.tar.xz
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
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td27
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td55
2 files changed, 71 insertions, 11 deletions
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<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
list<Predicate> 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<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
IndexMode im, Format f, InstrItinClass itin,
string opc, string asm, string cstr,
@@ -1148,6 +1148,22 @@ class Thumb2sI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
list<Predicate> 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<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
+ InstrItinClass itin,
+ string opc, string asm, string cstr, list<dag> pattern>
+ : InstARM<am, sz, IndexModeNone, ThumbFrm, GenericDomain, cstr, itin> {
+ 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<Predicate> Predicates = [IsThumb2];
+}
+
// Special cases
class Thumb2XI<dag oops, dag iops, AddrMode am, SizeFlagVal sz,
InstrItinClass itin,
@@ -1203,6 +1219,11 @@ class T2sI<dag oops, dag iops, InstrItinClass itin,
string opc, string asm, list<dag> pattern>
: Thumb2sI<oops, iops, AddrModeNone, Size4Bytes, itin, opc, asm, "", pattern>;
+class T2sI_cpsr<dag oops, dag iops, InstrItinClass itin,
+ string opc, string asm, list<dag> pattern>
+ : Thumb2sI_cpsr<oops, iops, AddrModeNone, Size4Bytes, itin, opc,
+ asm, "", pattern>;
+
class T2XI<dag oops, dag iops, InstrItinClass itin,
string asm, list<dag> pattern>
: Thumb2XI<oops, iops, AddrModeNone, Size4Bytes, itin, asm, "", pattern>;
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<bits<4> 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<bits<4> 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<bits<4> 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<bits<4> 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<bits<4> 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<bits<4> 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<bits<4> opcod, string opc, PatFrag opnode,
// the ".w" prefix to indicate that they are wide.
multiclass T2I_bin_w_irs<bits<4> opcod, string opc, PatFrag opnode,
bit Commutable = 0> :
- T2I_bin_irs<opcod, opc, opnode, Commutable, ".w", ?>;
+ T2I_bin_irs<opcod, opc, opnode, Commutable, ".w">;
/// T2I_bin_sw_irs - Same as T2I_bin_w_irs except these operations set
// the 'S' bit.
multiclass T2I_bin_sw_irs<bits<4> opcod, string opc, PatFrag opnode,
bit Commutable = 0> :
- T2I_bin_irs<opcod, opc, opnode, Commutable, ".w", 1>;
+ T2I_bin_cpsr_irs<opcod, opc, opnode, Commutable, ".w">;
/// 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