aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/AsmParser
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-10-18 00:22:00 +0000
committerJim Grosbach <grosbach@apple.com>2011-10-18 00:22:00 +0000
commit6248a546f23e7ffa84c171dc364b922e28467275 (patch)
tree954e7c55918cd18a5bd4abc891f418288c87c82a /lib/Target/ARM/AsmParser
parent4984d647daada693b8bdff5c3f4b0d476015ef2a (diff)
downloadexternal_llvm-6248a546f23e7ffa84c171dc364b922e28467275.zip
external_llvm-6248a546f23e7ffa84c171dc364b922e28467275.tar.gz
external_llvm-6248a546f23e7ffa84c171dc364b922e28467275.tar.bz2
ARM assembly parsing and encoding for VMOV/VMVN/VORR/VBIC.i32.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142321 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/AsmParser')
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp59
1 files changed, 59 insertions, 0 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 11b6574..752d351 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -935,6 +935,37 @@ public:
return (Value >= 0 && Value < 256) || (Value >= 0x0100 && Value <= 0xff00);
}
+ bool isNEONi32splat() const {
+ if (Kind != k_Immediate)
+ return false;
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ // Must be a constant.
+ if (!CE) return false;
+ int64_t Value = CE->getValue();
+ // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X.
+ return (Value >= 0 && Value < 256) ||
+ (Value >= 0x0100 && Value <= 0xff00) ||
+ (Value >= 0x010000 && Value <= 0xff0000) ||
+ (Value >= 0x01000000 && Value <= 0xff000000);
+ }
+
+ bool isNEONi32vmov() const {
+ if (Kind != k_Immediate)
+ return false;
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ // Must be a constant.
+ if (!CE) return false;
+ int64_t Value = CE->getValue();
+ // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
+ // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
+ return (Value >= 0 && Value < 256) ||
+ (Value >= 0x0100 && Value <= 0xff00) ||
+ (Value >= 0x010000 && Value <= 0xff0000) ||
+ (Value >= 0x01000000 && Value <= 0xff000000) ||
+ (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
+ (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
+ }
+
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
// Add as immediates when possible. Null MCExpr = 0.
if (Expr == 0)
@@ -1477,6 +1508,34 @@ public:
Inst.addOperand(MCOperand::CreateImm(Value));
}
+ void addNEONi32splatOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ // The immediate encodes the type of constant as well as the value.
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ unsigned Value = CE->getValue();
+ if (Value >= 256 && Value <= 0xff00)
+ Value = (Value >> 8) | 0x200;
+ else if (Value > 0xffff && Value <= 0xff0000)
+ Value = (Value >> 16) | 0x400;
+ else if (Value > 0xffffff)
+ Value = (Value >> 24) | 0x600;
+ Inst.addOperand(MCOperand::CreateImm(Value));
+ }
+
+ void addNEONi32vmovOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ // The immediate encodes the type of constant as well as the value.
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+ unsigned Value = CE->getValue();
+ if (Value >= 256 && Value <= 0xffff)
+ Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200);
+ else if (Value > 0xffff && Value <= 0xffffff)
+ Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400);
+ else if (Value > 0xffffff)
+ Value = (Value >> 24) | 0x600;
+ Inst.addOperand(MCOperand::CreateImm(Value));
+ }
+
virtual void print(raw_ostream &OS) const;
static ARMOperand *CreateITMask(unsigned Mask, SMLoc S) {