summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-06-27 23:54:06 +0000
committerJim Grosbach <grosbach@apple.com>2011-06-27 23:54:06 +0000
commita6f7a1efcc4b8861cbcf22419a34d3a6037834ef (patch)
tree818c92ccd53d20cc1d35a29beb2ab0d6bd4316e0 /llvm/lib
parent40e978f7b331df942709e8ca20b8c6bce076eaac (diff)
downloadbcm5719-llvm-a6f7a1efcc4b8861cbcf22419a34d3a6037834ef.tar.gz
bcm5719-llvm-a6f7a1efcc4b8861cbcf22419a34d3a6037834ef.zip
ARM Assembly support for Thumb mov-immediate.
Correctly parse the forms of the Thumb mov-immediate instruction: 1. 8-bit immediate 0-255. 2. 12-bit shifted-immediate. The 16-bit immediate "movw" form is also legal with just a "mov" mnemonic, but is not yet supported. More parser logic necessary there due to fixups. llvm-svn: 133966
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb.td9
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb2.td9
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp26
3 files changed, 40 insertions, 4 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb.td b/llvm/lib/Target/ARM/ARMInstrThumb.td
index 44fbc021d86..328d330800b 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb.td
@@ -34,9 +34,10 @@ def imm0_7_neg : PatLeaf<(i32 imm), [{
return (uint32_t)-N->getZExtValue() < 8;
}], imm_neg_XFORM>;
-def imm0_255 : ImmLeaf<i32, [{
- return Imm >= 0 && Imm < 256;
-}]>;
+def imm0_255_asmoperand : AsmOperandClass { let Name = "Imm0_255"; }
+def imm0_255 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> {
+ let ParserMatchClass = imm0_255_asmoperand;
+}
def imm0_255_comp : PatLeaf<(i32 imm), [{
return ~((uint32_t)N->getZExtValue()) < 256;
}]>;
@@ -1072,7 +1073,7 @@ def tLSRrr : // A8.6.91
// Move register
let isMoveImm = 1 in
-def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins i32imm:$imm8), IIC_iMOVi,
+def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins imm0_255:$imm8), IIC_iMOVi,
"mov", "\t$Rd, $imm8",
[(set tGPR:$Rd, imm0_255:$imm8)]>,
T1General<{1,0,0,?,?}> {
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index 090670b8986..f36a49e9434 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -44,9 +44,11 @@ def t2_so_imm_neg_XFORM : SDNodeXForm<imm, [{
// 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.
+def t2_so_imm_asmoperand : AsmOperandClass { let Name = "T2SOImm"; }
def t2_so_imm : Operand<i32>, ImmLeaf<i32, [{
return ARM_AM::getT2SOImmVal(Imm) != -1;
}]> {
+ let ParserMatchClass = t2_so_imm_asmoperand;
let EncoderMethod = "getT2SOImmOpValue";
}
@@ -1645,6 +1647,10 @@ def t2MOVi : T2sOneRegImm<(outs rGPR:$Rd), (ins t2_so_imm:$imm), IIC_iMOVi,
let Inst{15} = 0;
}
+def : InstAlias<"mov${s}${p} $Rd, $imm", (t2MOVi rGPR:$Rd, t2_so_imm:$imm,
+ pred:$p, cc_out:$s)>,
+ Requires<[IsThumb2]>;
+
let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in
def t2MOVi16 : T2I<(outs rGPR:$Rd), (ins i32imm_hilo16:$imm), IIC_iMOVi,
"movw", "\t$Rd, $imm",
@@ -2709,6 +2715,8 @@ def t2MOVCCr : T2TwoReg<
let Inst{7-4} = 0b0000;
}
+// FIXME: Pseudo-ize these. For now, just mark codegen only.
+let isCodeGenOnly = 1 in {
let isMoveImm = 1 in
def t2MOVCCi : T2OneRegImm<(outs rGPR:$Rd), (ins rGPR:$false, t2_so_imm:$imm),
IIC_iCMOVi, "mov", ".w\t$Rd, $imm",
@@ -2789,6 +2797,7 @@ def t2MOVCCror : T2I_movcc_sh<0b11, (outs rGPR:$Rd),
IIC_iCMOVsi, "ror", ".w\t$Rd, $Rm, $imm", []>,
RegConstraint<"$false = $Rd">;
} // neverHasSideEffects
+} // isCodeGenOnly = 1
//===----------------------------------------------------------------------===//
// Atomic operations intrinsics
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 8fe504fb2bb..178fe5229db 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -350,6 +350,22 @@ public:
bool isCondCode() const { return Kind == CondCode; }
bool isCCOut() const { return Kind == CCOut; }
bool isImm() const { return Kind == Immediate; }
+ bool isImm0_255() const {
+ if (Kind != Immediate)
+ return false;
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ if (!CE) return false;
+ int64_t Value = CE->getValue();
+ return Value >= 0 && Value < 256;
+ }
+ bool isT2SOImm() const {
+ if (Kind != Immediate)
+ return false;
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ if (!CE) return false;
+ int64_t Value = CE->getValue();
+ return ARM_AM::getT2SOImmVal(Value) != -1;
+ }
bool isReg() const { return Kind == Register; }
bool isRegList() const { return Kind == RegisterList; }
bool isDPRRegList() const { return Kind == DPRRegisterList; }
@@ -515,6 +531,16 @@ public:
addExpr(Inst, getImm());
}
+ void addImm0_255Operands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ addExpr(Inst, getImm());
+ }
+
+ void addT2SOImmOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ addExpr(Inst, getImm());
+ }
+
void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
OpenPOWER on IntegriCloud