summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2011-08-11 20:28:23 +0000
committerJim Grosbach <grosbach@apple.com>2011-08-11 20:28:23 +0000
commit14605d1a679d55ff25875656e100ff455194ee17 (patch)
tree895f59afdf4c201fc1f4e224201d4e31972bfa0e
parentc12d9b9dfbba233c847f74facf3c0deafae4523f (diff)
downloadllvm-14605d1a679d55ff25875656e100ff455194ee17.tar.gz
llvm-14605d1a679d55ff25875656e100ff455194ee17.tar.bz2
llvm-14605d1a679d55ff25875656e100ff455194ee17.tar.xz
ARM STRD assembly parsing and encoding.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137342 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMInstrFormats.td29
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td55
-rw-r--r--lib/Target/ARM/AsmParser/ARMAsmParser.cpp32
-rw-r--r--test/MC/ARM/arm-memory-instructions.s39
4 files changed, 93 insertions, 62 deletions
diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td
index 579f3835bc..343dee5562 100644
--- a/lib/Target/ARM/ARMInstrFormats.td
+++ b/lib/Target/ARM/ARMInstrFormats.td
@@ -680,35 +680,6 @@ class AI3sthpr<dag oops, dag iops, Format f, InstrItinClass itin,
let Inst{24} = 1; // P bit
let Inst{27-25} = 0b000;
}
-class AI3stdpr<dag oops, dag iops, Format f, InstrItinClass itin,
- string opc, string asm, string cstr, list<dag> pattern>
- : I<oops, iops, AddrMode3, 4, IndexModePre, f, itin,
- opc, asm, cstr, pattern> {
- let Inst{4} = 1;
- let Inst{5} = 1; // H bit
- let Inst{6} = 1; // S bit
- let Inst{7} = 1;
- let Inst{20} = 0; // L bit
- let Inst{21} = 1; // W bit
- let Inst{24} = 1; // P bit
- let Inst{27-25} = 0b000;
-}
-
-// Post-indexed stores
-class AI3stdpo<dag oops, dag iops, Format f, InstrItinClass itin,
- string opc, string asm, string cstr, list<dag> pattern>
- : I<oops, iops, AddrMode3, 4, IndexModePost, f, itin,
- opc, asm, cstr, pattern> {
- let Inst{4} = 1;
- let Inst{5} = 1; // H bit
- let Inst{6} = 1; // S bit
- let Inst{7} = 1;
- let Inst{20} = 0; // L bit
- let Inst{21} = 0; // W bit
- let Inst{24} = 0; // P bit
- let Inst{27-25} = 0b000;
-}
-
// addrmode4 instructions
class AXI4<dag oops, dag iops, IndexMode im, Format f, InstrItinClass itin,
string asm, string cstr, list<dag> pattern>
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index c8eb025731..df86d12266 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -2369,42 +2369,35 @@ def STRH_POST: AI3stridx<0b1011, 0, 0, (outs GPR:$Rn_wb),
[(set GPR:$Rn_wb, (post_truncsti16 GPR:$Rt,
GPR:$Rn, am3offset:$offset))]>;
-// For disassembly only
let mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1 in {
-def STRD_PRE : AI3stdpr<(outs GPR:$base_wb),
- (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
- StMiscFrm, IIC_iStore_d_ru,
- "strd", "\t$src1, $src2, [$base, $offset]!",
- "$base = $base_wb", []> {
- bits<4> src1;
- bits<4> base;
- bits<10> offset;
- let Inst{23} = offset{8}; // U bit
- let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
- let Inst{19-16} = base;
- let Inst{15-12} = src1;
- let Inst{11-8} = offset{7-4};
- let Inst{3-0} = offset{3-0};
-
+def STRD_PRE : AI3ldstidx<0b1111, 0, 1, 1, (outs GPR:$Rn_wb),
+ (ins GPR:$Rt, GPR:$Rt2, addrmode3:$addr),
+ IndexModePre, StMiscFrm, IIC_iStore_d_ru,
+ "strd", "\t$Rt, $Rt2, $addr!",
+ "$addr.base = $Rn_wb", []> {
+ bits<14> addr;
+ let Inst{23} = addr{8}; // U bit
+ let Inst{22} = addr{13}; // 1 == imm8, 0 == Rm
+ let Inst{19-16} = addr{12-9}; // Rn
+ let Inst{11-8} = addr{7-4}; // imm7_4/zero
+ let Inst{3-0} = addr{3-0}; // imm3_0/Rm
let DecoderMethod = "DecodeAddrMode3Instruction";
+ let AsmMatchConverter = "cvtStrdPre";
}
-// For disassembly only
-def STRD_POST: AI3stdpo<(outs GPR:$base_wb),
- (ins GPR:$src1, GPR:$src2, GPR:$base, am3offset:$offset),
- StMiscFrm, IIC_iStore_d_ru,
- "strd", "\t$src1, $src2, [$base], $offset",
- "$base = $base_wb", []> {
- bits<4> src1;
- bits<4> base;
+def STRD_POST: AI3ldstidx<0b1111, 0, 1, 0, (outs GPR:$Rn_wb),
+ (ins GPR:$Rt, GPR:$Rt2, addr_offset_none:$addr,
+ am3offset:$offset),
+ IndexModePost, StMiscFrm, IIC_iStore_d_ru,
+ "strd", "\t$Rt, $Rt2, $addr, $offset",
+ "$addr.base = $Rn_wb", []> {
bits<10> offset;
- let Inst{23} = offset{8}; // U bit
- let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
- let Inst{19-16} = base;
- let Inst{15-12} = src1;
- let Inst{11-8} = offset{7-4};
- let Inst{3-0} = offset{3-0};
-
+ bits<4> addr;
+ let Inst{23} = offset{8}; // U bit
+ let Inst{22} = offset{9}; // 1 == imm8, 0 == Rm
+ let Inst{19-16} = addr;
+ let Inst{11-8} = offset{7-4}; // imm7_4/zero
+ let Inst{3-0} = offset{3-0}; // imm3_0/Rm
let DecoderMethod = "DecodeAddrMode3Instruction";
}
} // mayStore = 1, neverHasSideEffects = 1, hasExtraSrcRegAllocReq = 1
diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 31d2b807ed..fc8a484701 100644
--- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -133,6 +133,8 @@ class ARMAsmParser : public MCTargetAsmParser {
const SmallVectorImpl<MCParsedAsmOperand*> &);
bool cvtLdrdPre(MCInst &Inst, unsigned Opcode,
const SmallVectorImpl<MCParsedAsmOperand*> &);
+ bool cvtStrdPre(MCInst &Inst, unsigned Opcode,
+ const SmallVectorImpl<MCParsedAsmOperand*> &);
bool cvtLdWriteBackRegAddrMode3(MCInst &Inst, unsigned Opcode,
const SmallVectorImpl<MCParsedAsmOperand*> &);
@@ -2224,6 +2226,24 @@ cvtLdrdPre(MCInst &Inst, unsigned Opcode,
return true;
}
+/// cvtStrdPre - Convert parsed operands to MCInst.
+/// Needed here because the Asm Gen Matcher can't handle properly tied operands
+/// when they refer multiple MIOperands inside a single one.
+bool ARMAsmParser::
+cvtStrdPre(MCInst &Inst, unsigned Opcode,
+ const SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ // Create a writeback register dummy placeholder.
+ Inst.addOperand(MCOperand::CreateImm(0));
+ // Rt, Rt2
+ ((ARMOperand*)Operands[2])->addRegOperands(Inst, 1);
+ ((ARMOperand*)Operands[3])->addRegOperands(Inst, 1);
+ // addr
+ ((ARMOperand*)Operands[4])->addAddrMode3Operands(Inst, 3);
+ // pred
+ ((ARMOperand*)Operands[1])->addCondCodeOperands(Inst, 2);
+ return true;
+}
+
/// cvtLdWriteBackRegAddrMode3 - Convert parsed operands to MCInst.
/// Needed here because the Asm Gen Matcher can't handle properly tied operands
/// when they refer multiple MIOperands inside a single one.
@@ -2850,7 +2870,15 @@ validateInstruction(MCInst &Inst,
"destination operands must be sequential");
return false;
}
- case ARM::STRD:
+ case ARM::STRD: {
+ // Rt2 must be Rt + 1.
+ unsigned Rt = getARMRegisterNumbering(Inst.getOperand(0).getReg());
+ unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(1).getReg());
+ if (Rt2 != Rt + 1)
+ return Error(Operands[3]->getStartLoc(),
+ "source operands must be sequential");
+ return false;
+ }
case ARM::STRD_PRE:
case ARM::STRD_POST:
case ARM::STREXD: {
@@ -2858,7 +2886,7 @@ validateInstruction(MCInst &Inst,
unsigned Rt = getARMRegisterNumbering(Inst.getOperand(1).getReg());
unsigned Rt2 = getARMRegisterNumbering(Inst.getOperand(2).getReg());
if (Rt2 != Rt + 1)
- return Error(Operands[4]->getStartLoc(),
+ return Error(Operands[3]->getStartLoc(),
"source operands must be sequential");
return false;
}
diff --git a/test/MC/ARM/arm-memory-instructions.s b/test/MC/ARM/arm-memory-instructions.s
index 8af12063e0..49b4216f88 100644
--- a/test/MC/ARM/arm-memory-instructions.s
+++ b/test/MC/ARM/arm-memory-instructions.s
@@ -389,3 +389,42 @@ _func:
@ CHECK: strbt r5, [r6], #-13 @ encoding: [0x0d,0x50,0x66,0xe4]
@ CHECK: strbt r4, [r9], r5 @ encoding: [0x05,0x40,0xe9,0xe6]
@ CHECK: strbt r3, [r8], -r2, lsl #3 @ encoding: [0x82,0x31,0x68,0xe6]
+
+
+@------------------------------------------------------------------------------
+@ STRD (immediate)
+@------------------------------------------------------------------------------
+ strd r1, r2, [r4]
+ strd r2, r3, [r6, #1]
+ strd r3, r4, [r7, #22]!
+ strd r4, r5, [r8], #7
+ strd r5, r6, [sp], #0
+ strd r6, r7, [lr], #+0
+ strd r7, r8, [r9], #-0
+
+@ CHECK: strd r1, r2, [r4] @ encoding: [0xf0,0x10,0xc4,0xe1]
+@ CHECK: strd r2, r3, [r6, #1] @ encoding: [0xf1,0x20,0xc6,0xe1]
+@ CHECK: strd r3, r4, [r7, #22]! @ encoding: [0xf6,0x31,0xe7,0xe1]
+@ CHECK: strd r4, r5, [r8], #7 @ encoding: [0xf7,0x40,0xc8,0xe0]
+@ CHECK: strd r5, r6, [sp], #0 @ encoding: [0xf0,0x50,0xcd,0xe0]
+@ CHECK: strd r6, r7, [lr], #0 @ encoding: [0xf0,0x60,0xce,0xe0]
+@ CHECK: strd r7, r8, [r9], #-0 @ encoding: [0xf0,0x70,0x49,0xe0]
+
+
+@------------------------------------------------------------------------------
+@ FIXME: STRD (label)
+@------------------------------------------------------------------------------
+
+@------------------------------------------------------------------------------
+@ STRD (register)
+@------------------------------------------------------------------------------
+ strd r8, r9, [r4, r1]
+ strd r7, r8, [r3, r9]!
+ strd r6, r7, [r5], r8
+ strd r5, r6, [r12], -r10
+
+@ CHECK: strd r8, r9, [r4, r1] @ encoding: [0xf1,0x80,0x84,0xe1]
+@ CHECK: strd r7, r8, [r3, r9]! @ encoding: [0xf9,0x70,0xa3,0xe1]
+@ CHECK: strd r6, r7, [r5], r8 @ encoding: [0xf8,0x60,0x85,0xe0]
+@ CHECK: strd r5, r6, [r12], -r10 @ encoding: [0xfa,0x50,0x0c,0xe0]
+