[llvm-commits] [llvm] r120408 - in /llvm/trunk: lib/Target/ARM/ARMCodeEmitter.cpp lib/Target/ARM/ARMInstrThumb.td lib/Target/ARM/ARMMCCodeEmitter.cpp lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/thumb.s
Bill Wendling
isanbard at gmail.com
Mon Nov 29 23:44:32 PST 2010
Author: void
Date: Tue Nov 30 01:44:32 2010
New Revision: 120408
URL: http://llvm.org/viewvc/llvm-project?rev=120408&view=rev
Log:
Add parsing for the Thumb t_addrmode_s4 addressing mode. This can almost
certainly be made more generic. But it does allow us to parse something like:
ldr r3, [r2, r4]
correctly in Thumb mode.
Modified:
llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/trunk/test/MC/ARM/thumb.s
Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=120408&r1=120407&r2=120408&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue Nov 30 01:44:32 2010
@@ -235,8 +235,10 @@
const { return 0;}
uint32_t getAddrMode3OffsetOpValue(const MachineInstr &MI, unsigned OpIdx)
const { return 0;}
- uint32_t getAddrMode3OpValue(const MachineInstr &MI, unsigned Op) const
- { return 0; }
+ uint32_t getAddrMode3OpValue(const MachineInstr &MI, unsigned Op)
+ const { return 0; }
+ uint32_t getAddrModeS4OpValue(const MachineInstr &MI, unsigned Op)
+ const { return 0; }
uint32_t getAddrMode5OpValue(const MachineInstr &MI, unsigned Op) const {
// {17-13} = reg
// {12} = (U)nsigned (add == '1', sub == '0')
Modified: llvm/trunk/lib/Target/ARM/ARMInstrThumb.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrThumb.td?rev=120408&r1=120407&r2=120408&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrThumb.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrThumb.td Tue Nov 30 01:44:32 2010
@@ -74,6 +74,11 @@
// Define Thumb specific addressing modes.
+def MemModeThumbAsmOperand : AsmOperandClass {
+ let Name = "MemModeThumb";
+ let SuperClasses = [];
+}
+
// t_addrmode_rr := reg + reg
//
def t_addrmode_rr : Operand<i32>,
@@ -87,8 +92,10 @@
//
def t_addrmode_s4 : Operand<i32>,
ComplexPattern<i32, 3, "SelectThumbAddrModeS4", []> {
+ string EncoderMethod = "getAddrModeS4OpValue";
let PrintMethod = "printThumbAddrModeS4Operand";
let MIOperandInfo = (ops tGPR:$base, i32imm:$offsimm, tGPR:$offsreg);
+ let ParserMatchClass = MemModeThumbAsmOperand;
}
// t_addrmode_s2 := reg + reg
@@ -489,8 +496,7 @@
let Inst{7-0} = imm;
}
-// A8.6.16 B: Encoding T1
-// If Inst{11-8} == 0b1110 then UNDEFINED
+// The assembler uses 0xDEFE for a trap instruction.
let isBarrier = 1, isTerminator = 1 in
def tTRAP : TI<(outs), (ins), IIC_Br,
"trap", [(trap)]>, Encoding16 {
@@ -505,12 +511,26 @@
def tLDR : T1pI4<(outs tGPR:$Rt), (ins t_addrmode_s4:$addr), IIC_iLoad_r,
"ldr", "\t$Rt, $addr",
[(set tGPR:$Rt, (load t_addrmode_s4:$addr))]>,
- T1LdSt<0b100>;
+ T1LdSt<0b100> {
+ // A8.6.60
+ bits<3> Rt;
+ bits<8> addr;
+ let Inst{8-6} = addr{5-3}; // Rm
+ let Inst{5-3} = addr{2-0}; // Rn
+ let Inst{2-0} = Rt;
+}
-def tLDRi: T1pI4<(outs tGPR:$dst), (ins t_addrmode_s4:$addr), IIC_iLoad_r,
- "ldr", "\t$dst, $addr",
+def tLDRi: T1pI4<(outs tGPR:$Rt), (ins t_addrmode_s4:$addr), IIC_iLoad_r,
+ "ldr", "\t$Rt, $addr",
[]>,
- T1LdSt4Imm<{1,?,?}>;
+ T1LdSt4Imm<{1,?,?}> {
+ // A8.6.57
+ bits<3> Rt;
+ bits<8> addr;
+ let Inst{10-6} = addr{7-3}; // imm5
+ let Inst{5-3} = addr{2-0}; // Rn
+ let Inst{2-0} = Rt;
+}
def tLDRB : T1pI1<(outs tGPR:$dst), (ins t_addrmode_s1:$addr), IIC_iLoad_bh_r,
"ldrb", "\t$dst, $addr",
Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=120408&r1=120407&r2=120408&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Tue Nov 30 01:44:32 2010
@@ -136,6 +136,10 @@
uint32_t getAddrMode3OpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const;
+ /// getAddrModeS4OpValue - Return encoding for t_addrmode_s4 operands.
+ uint32_t getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
SmallVectorImpl<MCFixup> &Fixups) const;
@@ -540,6 +544,26 @@
return (Rn << 9) | Imm8 | (isAdd << 8) | (isImm << 13);
}
+/// getAddrModeS4OpValue - Return encoding for t_addrmode_s4 operands.
+uint32_t ARMMCCodeEmitter::
+getAddrModeS4OpValue(const MCInst &MI, unsigned OpIdx,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ // [Rn, Rm]
+ // {5-3} = Rm
+ // {2-0} = Rn
+ //
+ // [Rn, #imm]
+ // {7-3} = imm5
+ // {2-0} = Rn
+ const MCOperand &MO = MI.getOperand(OpIdx);
+ const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
+ const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
+ unsigned Rn = getARMRegisterNumbering(MO.getReg());
+ unsigned Imm5 = MO1.getImm();
+ unsigned Rm = getARMRegisterNumbering(MO2.getReg());
+ return (Rm << 3) | (Imm5 << 3) | Rn;
+}
+
/// getAddrMode5OpValue - Return encoding info for 'reg +/- imm12' operand.
uint32_t ARMMCCodeEmitter::
getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=120408&r1=120407&r2=120408&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Tue Nov 30 01:44:32 2010
@@ -222,16 +222,30 @@
if (!isMemory() || Mem.OffsetIsReg || Mem.OffsetRegShifted ||
Mem.Writeback || Mem.Negative)
return false;
+
// If there is an offset expression, make sure it's valid.
- if (!Mem.Offset)
- return true;
+ if (!Mem.Offset) return true;
+
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
- if (!CE)
- return false;
+ if (!CE) return false;
+
// The offset must be a multiple of 4 in the range 0-1020.
int64_t Value = CE->getValue();
return ((Value & 0x3) == 0 && Value <= 1020 && Value >= -1020);
}
+ bool isMemModeThumb() const {
+ if (!isMemory() || (!Mem.OffsetIsReg && !Mem.Offset) || Mem.Writeback)
+ return false;
+
+ if (!Mem.Offset) return true;
+
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
+ if (!CE) return false;
+
+ // The offset must be a multiple of 4 in the range 0-124.
+ uint64_t Value = CE->getValue();
+ return ((Value & 0x3) == 0 && Value <= 124);
+ }
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
// Add as immediates when possible. Null MCExpr = 0.
@@ -302,6 +316,21 @@
}
}
+ void addMemModeThumbOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 3 && isMemModeThumb() && "Invalid number of operands!");
+ Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
+
+ if (Mem.Offset) {
+ const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Mem.Offset);
+ assert(CE && "Non-constant mode offset operand!");
+ Inst.addOperand(MCOperand::CreateImm(CE->getValue() / 4));
+ Inst.addOperand(MCOperand::CreateReg(0));
+ } else {
+ Inst.addOperand(MCOperand::CreateImm(0));
+ Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
+ }
+ }
+
virtual void dump(raw_ostream &OS) const;
static ARMOperand *CreateCondCode(ARMCC::CondCodes CC, SMLoc S) {
@@ -592,8 +621,8 @@
int OffsetRegNum;
bool OffsetRegShifted;
enum ShiftType ShiftType;
- const MCExpr *ShiftAmount;
- const MCExpr *Offset;
+ const MCExpr *ShiftAmount = 0;
+ const MCExpr *Offset = 0;
if (ParseMemoryOffsetReg(Negative, OffsetRegShifted, ShiftType, ShiftAmount,
Offset, OffsetIsReg, OffsetRegNum, E))
return true;
Modified: llvm/trunk/test/MC/ARM/thumb.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb.s?rev=120408&r1=120407&r2=120408&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb.s (original)
+++ llvm/trunk/test/MC/ARM/thumb.s Tue Nov 30 01:44:32 2010
@@ -32,3 +32,6 @@
@ CHECK: uxth r3, r6 @ encoding: [0xb3,0xb2]
uxtb r3, r6
uxth r3, r6
+
+@ CHECK: ldr r3, [r1, r2] @ encoding: [0x8b,0x58]
+ ldr r3, [r1, r2]
More information about the llvm-commits
mailing list