aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-07-06 22:23:46 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-07-06 22:23:46 +0000
commit299ee654a2c92e1909144b23cf470a3be5a91d5d (patch)
tree6ef41b461b1d6a0d80d7cd03b292e8c68726986b /lib/Target/ARM
parentc8147e1cc967c50f72158cc93ee538a671a85f31 (diff)
downloadexternal_llvm-299ee654a2c92e1909144b23cf470a3be5a91d5d.zip
external_llvm-299ee654a2c92e1909144b23cf470a3be5a91d5d.tar.gz
external_llvm-299ee654a2c92e1909144b23cf470a3be5a91d5d.tar.bz2
Add bfc to armv6t2.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74868 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r--lib/Target/ARM/ARMCodeEmitter.cpp5
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td30
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td48
3 files changed, 48 insertions, 35 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp
index 4732700..b168605 100644
--- a/lib/Target/ARM/ARMCodeEmitter.cpp
+++ b/lib/Target/ARM/ARMCodeEmitter.cpp
@@ -741,6 +741,11 @@ void Emitter<CodeEmitter>::emitDataProcessingInstruction(
unsigned ImplicitRn) {
const TargetInstrDesc &TID = MI.getDesc();
+ if (TID.Opcode == ARM::BFC) {
+ cerr << "ERROR: ARMv6t2 JIT is not yet supported.\n";
+ abort();
+ }
+
// Part of binary is determined by TableGn.
unsigned Binary = getBinaryCodeForInstr(MI);
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 1916a3b..1433b10 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -170,6 +170,27 @@ def sext_16_node : PatLeaf<(i32 GPR:$a), [{
return CurDAG->ComputeNumSignBits(SDValue(N,0)) >= 17;
}]>;
+/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
+/// e.g., 0xf000ffff
+def bf_inv_mask_imm : Operand<i32>,
+ PatLeaf<(imm), [{
+ uint32_t v = (uint32_t)N->getZExtValue();
+ if (v == 0xffffffff)
+ return 0;
+ // naive checker. should do better, but simple is best for now since it's
+ // more likely to be correct.
+ while (v & 1) v >>= 1; // shift off the leading 1's
+ if (v)
+ {
+ while (!(v & 1)) v >>=1; // shift off the mask
+ while (v & 1) v >>= 1; // shift off the trailing 1's
+ }
+ // if this is a mask for clearing a bitfield, what's left should be zero.
+ return (v == 0);
+}] > {
+ let PrintMethod = "printBitfieldInvMaskImmOperand";
+}
+
class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
class UnOpFrag <dag res> : PatFrag<(ops node:$Src), res>;
@@ -993,6 +1014,15 @@ defm EOR : AsI1_bin_irs<0b0001, "eor",
defm BIC : AsI1_bin_irs<0b1110, "bic",
BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
+def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
+ AddrMode1, Size4Bytes, IndexModeNone, DPFrm,
+ "bfc", " $dst, $imm", "$src = $dst",
+ [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>,
+ Requires<[IsARM, HasV6T2]> {
+ let Inst{27-21} = 0b0111110;
+ let Inst{6-0} = 0b0011111;
+}
+
def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm,
"mvn", " $dst, $src",
[(set GPR:$dst, (not GPR:$src))]>, UnaryDP;
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 50345a6..85edae4 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -89,27 +89,6 @@ def imm0_65535 : PatLeaf<(i32 imm), [{
return (uint32_t)N->getZExtValue() < 65536;
}]>;
-/// bf_inv_mask_imm predicate - An AND mask to clear an arbitrary width bitfield
-/// e.g., 0xf000ffff
-def bf_inv_mask_imm : Operand<i32>,
- PatLeaf<(imm), [{
- uint32_t v = (uint32_t)N->getZExtValue();
- if (v == 0xffffffff)
- return 0;
- // naive checker. should do better, but simple is best for now since it's
- // more likely to be correct.
- while (v & 1) v >>= 1; // shift off the leading 1's
- if (v)
- {
- while (!(v & 1)) v >>=1; // shift off the mask
- while (v & 1) v >>= 1; // shift off the trailing 1's
- }
- // if this is a mask for clearing a bitfield, what's left should be zero.
- return (v == 0);
-}] > {
- let PrintMethod = "printBitfieldInvMaskImmOperand";
-}
-
/// Split a 32-bit immediate into two 16 bit parts.
def t2_lo16 : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant((uint32_t)N->getZExtValue() & 0xffff,
@@ -820,29 +799,28 @@ defm t2EOR : T2I_bin_irs<"eor", BinOpFrag<(xor node:$LHS, node:$RHS)>, 1>;
defm t2BIC : T2I_bin_irs<"bic", BinOpFrag<(and node:$LHS, (not node:$RHS))>>;
-def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
- (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
+let Constraints = "$src = $dst" in
+def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
+ "bfc", " $dst, $imm",
+ [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>;
-defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
+// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
-def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
- (t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
+defm t2ORN : T2I_bin_irs<"orn", BinOpFrag<(or node:$LHS, (not node:$RHS))>>;
// Prefer over of t2EORri ra, rb, -1 because mvn has 16-bit version
let AddedComplexity = 1 in
defm t2MVN : T2I_un_irs <"mvn", UnOpFrag<(not node:$Src)>, 1, 1>;
-def : T2Pat<(t2_so_imm_not:$src),
- (t2MVNi t2_so_imm_not:$src)>;
-// A8.6.17 BFC - Bitfield clear
-// FIXME: Also available in ARM mode.
-let Constraints = "$src = $dst" in
-def t2BFC : T2I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm),
- "bfc", " $dst, $imm",
- [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>;
+def : T2Pat<(and GPR:$src, t2_so_imm_not:$imm),
+ (t2BICri GPR:$src, t2_so_imm_not:$imm)>;
-// FIXME: A8.6.18 BFI - Bitfield insert (Encoding T1)
+def : T2Pat<(or GPR:$src, t2_so_imm_not:$imm),
+ (t2ORNri GPR:$src, t2_so_imm_not:$imm)>;
+
+def : T2Pat<(t2_so_imm_not:$src),
+ (t2MVNi t2_so_imm_not:$src)>;
//===----------------------------------------------------------------------===//
// Multiply Instructions.