aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/ARM/AsmParser
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2011-07-21 18:54:16 +0000
committerOwen Anderson <resistor@mac.com>2011-07-21 18:54:16 +0000
commit92a202213bb4c20301abf6ab64e46df3695e60bf (patch)
treeea32134f1f818aa4c39815bf26129c890bff42e9 /lib/Target/ARM/AsmParser
parenta305fe75450348677a228f7d0f1cc53b2504b562 (diff)
Split up the ARM so_reg ComplexPattern into so_reg_reg and so_reg_imm, allowing us to distinguish the encodings that use shifted registers from those that use shifted immediates. This is necessary to allow the fixed-length decoder to distinguish things like BICS vs LDRH.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135693 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/AsmParser')
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp54
1 files changed, 49 insertions, 5 deletions
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 3232c5d675..ed5235ffba 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -172,6 +172,7 @@ class ARMOperand : public MCParsedAsmOperand {
DPRRegisterList,
SPRRegisterList,
ShiftedRegister,
+ ShiftedImmediate,
Shifter,
Token
} Kind;
@@ -241,6 +242,11 @@ class ARMOperand : public MCParsedAsmOperand {
unsigned ShiftReg;
unsigned ShiftImm;
} ShiftedReg;
+ struct {
+ ARM_AM::ShiftOpc ShiftTy;
+ unsigned SrcReg;
+ unsigned ShiftImm;
+ } ShiftedImm;
};
ARMOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
@@ -290,6 +296,9 @@ public:
case ShiftedRegister:
ShiftedReg = o.ShiftedReg;
break;
+ case ShiftedImmediate:
+ ShiftedImm = o.ShiftedImm;
+ break;
}
}
@@ -468,6 +477,7 @@ public:
bool isMemory() const { return Kind == Memory; }
bool isShifter() const { return Kind == Shifter; }
bool isShiftedReg() const { return Kind == ShiftedRegister; }
+ bool isShiftedImm() const { return Kind == ShiftedImmediate; }
bool isMemMode2() const {
if (getMemAddrMode() != ARMII::AddrMode2)
return false;
@@ -601,15 +611,25 @@ public:
void addShiftedRegOperands(MCInst &Inst, unsigned N) const {
assert(N == 3 && "Invalid number of operands!");
assert(isShiftedReg() && "addShiftedRegOperands() on non ShiftedReg!");
- assert((ShiftedReg.ShiftReg == 0 ||
- ARM_AM::getSORegOffset(ShiftedReg.ShiftImm) == 0) &&
- "Invalid shifted register operand!");
Inst.addOperand(MCOperand::CreateReg(ShiftedReg.SrcReg));
Inst.addOperand(MCOperand::CreateReg(ShiftedReg.ShiftReg));
Inst.addOperand(MCOperand::CreateImm(
ARM_AM::getSORegOpc(ShiftedReg.ShiftTy, ShiftedReg.ShiftImm)));
}
+ void addShiftedImmOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 3 && "Invalid number of operands!");
+ assert(isShiftedImm() && "addShiftedImmOperands() on non ShiftedImm!");
+ Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg));
+ if (ShiftedImm.ShiftTy == ARM_AM::rrx)
+ Inst.addOperand(MCOperand::CreateReg(ShiftedImm.SrcReg));
+ else
+ Inst.addOperand(MCOperand::CreateReg(0));
+ Inst.addOperand(MCOperand::CreateImm(
+ ARM_AM::getSORegOpc(ShiftedImm.ShiftTy, ShiftedImm.ShiftImm)));
+ }
+
+
void addShifterOperands(MCInst &Inst, unsigned N) const {
assert(N == 1 && "Invalid number of operands!");
Inst.addOperand(MCOperand::CreateImm(
@@ -885,6 +905,19 @@ public:
return Op;
}
+ static ARMOperand *CreateShiftedImmediate(ARM_AM::ShiftOpc ShTy,
+ unsigned SrcReg,
+ unsigned ShiftImm,
+ SMLoc S, SMLoc E) {
+ ARMOperand *Op = new ARMOperand(ShiftedImmediate);
+ Op->ShiftedImm.ShiftTy = ShTy;
+ Op->ShiftedImm.SrcReg = SrcReg;
+ Op->ShiftedImm.ShiftImm = ShiftImm;
+ Op->StartLoc = S;
+ Op->EndLoc = E;
+ return Op;
+ }
+
static ARMOperand *CreateShifter(ARM_AM::ShiftOpc ShTy,
SMLoc S, SMLoc E) {
ARMOperand *Op = new ARMOperand(Shifter);
@@ -1052,13 +1085,20 @@ void ARMOperand::print(raw_ostream &OS) const {
OS << "<shifter " << ARM_AM::getShiftOpcStr(Shift.ShiftTy) << ">";
break;
case ShiftedRegister:
- OS << "<so_reg"
+ OS << "<so_reg_reg "
<< ShiftedReg.SrcReg
<< ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedReg.ShiftImm))
<< ", " << ShiftedReg.ShiftReg << ", "
<< ARM_AM::getSORegOffset(ShiftedReg.ShiftImm)
<< ">";
break;
+ case ShiftedImmediate:
+ OS << "<so_reg_imm "
+ << ShiftedImm.SrcReg
+ << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(ShiftedImm.ShiftImm))
+ << ", " << ARM_AM::getSORegOffset(ShiftedImm.ShiftImm)
+ << ">";
+ break;
case RegisterList:
case DPRRegisterList:
case SPRRegisterList: {
@@ -1201,9 +1241,13 @@ int ARMAsmParser::TryParseShiftRegister(
}
}
- Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
+ if (ShiftReg && ShiftTy != ARM_AM::rrx)
+ Operands.push_back(ARMOperand::CreateShiftedRegister(ShiftTy, SrcReg,
ShiftReg, Imm,
S, Parser.getTok().getLoc()));
+ else
+ Operands.push_back(ARMOperand::CreateShiftedImmediate(ShiftTy, SrcReg, Imm,
+ S, Parser.getTok().getLoc()));
return 0;
}