summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorVolodymyr Turanskyy <volodymyr.turanskyy@arm.com>2018-07-04 16:11:15 +0000
committerVolodymyr Turanskyy <volodymyr.turanskyy@arm.com>2018-07-04 16:11:15 +0000
commit17c0c4e7424187c50c3189566aa3432cee7cdc9a (patch)
treecfa930e83ce5aad5e1943d33277b74cbf15e7aaf /llvm/lib
parenteaececf5e0c4c566838cf2bada8599e6346e59e7 (diff)
downloadbcm5719-llvm-17c0c4e7424187c50c3189566aa3432cee7cdc9a.tar.gz
bcm5719-llvm-17c0c4e7424187c50c3189566aa3432cee7cdc9a.zip
[ARM] [Assembler] Support negative immediates: cover few missing cases
Support for negative immediates was implemented in https://reviews.llvm.org/rL298380, however few instruction options were missing. This change adds negative immediates support and respective tests for the following: ADD ADDS ADDS.W AND.W ANDS BIC.W BICS BICS.W SUB SUBS SUBS.W Differential Revision: https://reviews.llvm.org/D48649 llvm-svn: 336286
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/ARM/ARMInstrThumb2.td18
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp9
2 files changed, 25 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index c9dd01b5854..034cb1db758 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -2104,6 +2104,12 @@ def : t2InstSubst<"sub${s}${p}.w $rd, $rn, $imm",
(t2ADDri GPRnopc:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
def : t2InstSubst<"subw${p} $rd, $rn, $imm",
(t2ADDri12 GPRnopc:$rd, GPR:$rn, t2_so_imm_neg:$imm, pred:$p)>;
+def : t2InstSubst<"subw${p} $Rd, $Rn, $imm",
+ (t2ADDri12 GPRnopc:$Rd, GPR:$Rn, imm0_4095_neg:$imm, pred:$p)>;
+def : t2InstSubst<"sub${s}${p} $rd, $rn, $imm",
+ (t2ADDri GPRnopc:$rd, GPRnopc:$rn, t2_so_imm_neg:$imm, pred:$p, s_cc_out:$s)>;
+def : t2InstSubst<"sub${p} $rd, $rn, $imm",
+ (t2ADDri12 GPRnopc:$rd, GPR:$rn, t2_so_imm_neg:$imm, pred:$p)>;
// RSB
defm t2RSB : T2I_rbin_irs <0b1110, "rsb", sub>;
@@ -4731,12 +4737,24 @@ def : t2InstSubst<"bic${s}${p} $Rd, $Rn, $imm",
def : t2InstSubst<"bic${s}${p} $Rdn, $imm",
(t2ANDri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_not:$imm,
pred:$p, cc_out:$s)>;
+def : t2InstSubst<"bic${s}${p}.w $Rd, $Rn, $imm",
+ (t2ANDri rGPR:$Rd, rGPR:$Rn, t2_so_imm_not:$imm,
+ pred:$p, cc_out:$s)>;
+def : t2InstSubst<"bic${s}${p}.w $Rdn, $imm",
+ (t2ANDri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_not:$imm,
+ pred:$p, cc_out:$s)>;
def : t2InstSubst<"and${s}${p} $Rd, $Rn, $imm",
(t2BICri rGPR:$Rd, rGPR:$Rn, t2_so_imm_not:$imm,
pred:$p, cc_out:$s)>;
def : t2InstSubst<"and${s}${p} $Rdn, $imm",
(t2BICri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_not:$imm,
pred:$p, cc_out:$s)>;
+def : t2InstSubst<"and${s}${p}.w $Rd, $Rn, $imm",
+ (t2BICri rGPR:$Rd, rGPR:$Rn, t2_so_imm_not:$imm,
+ pred:$p, cc_out:$s)>;
+def : t2InstSubst<"and${s}${p}.w $Rdn, $imm",
+ (t2BICri rGPR:$Rdn, rGPR:$Rdn, t2_so_imm_not:$imm,
+ pred:$p, cc_out:$s)>;
// And ORR <--> ORN
def : t2InstSubst<"orn${s}${p} $Rd, $Rn, $imm",
(t2ORRri rGPR:$Rd, rGPR:$Rn, t2_so_imm_not:$imm,
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index df2e7ff709f..318bfe90d1d 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -1030,7 +1030,12 @@ public:
if (!isImm()) return false;
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
if (!CE) return false;
- int64_t Value = -CE->getValue();
+ // isImm0_4095Neg is used with 32-bit immediates only.
+ // 32-bit immediates are zero extended to 64-bit when parsed,
+ // thus simple -CE->getValue() results in a big negative number,
+ // not a small positive number as intended
+ if ((CE->getValue() >> 32) > 0) return false;
+ uint32_t Value = -static_cast<uint32_t>(CE->getValue());
return Value > 0 && Value < 4096;
}
@@ -2242,7 +2247,7 @@ public:
// The operand is actually an imm0_4095, but we have its
// negation in the assembly source, so twiddle it here.
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
- Inst.addOperand(MCOperand::createImm(-CE->getValue()));
+ Inst.addOperand(MCOperand::createImm(-(uint32_t)CE->getValue()));
}
void addUnsignedOffset_b8s2Operands(MCInst &Inst, unsigned N) const {
OpenPOWER on IntegriCloud