[llvm-commits] [llvm] r139242 - in /llvm/trunk: lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/basic-thumb2-instructions.s
Jim Grosbach
grosbach at apple.com
Wed Sep 7 11:22:15 PDT 2011
On Sep 7, 2011, at 11:13 AM, Eli Friedman wrote:
> On Wed, Sep 7, 2011 at 11:05 AM, Jim Grosbach <grosbach at apple.com> wrote:
>> Author: grosbach
>> Date: Wed Sep 7 13:05:34 2011
>> New Revision: 139242
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=139242&view=rev
>> Log:
>> Thumb2 parsing and encoding for LDMIA.
>>
>> Choose 32-bit vs. 16-bit encoding when there's no .w suffix in post-processing
>> as match classes are insufficient to handle the context-sensitiveness of
>> the writeback operand's legality for the 16-bit encodings.
>>
>> Modified:
>> llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
>> llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s
>>
>> 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=139242&r1=139241&r2=139242&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
>> +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Wed Sep 7 13:05:34 2011
>> @@ -3339,6 +3339,17 @@
>> return false;
>> }
>>
>> +// Check if the specified regisgter is in the register list of the inst,
>> +// starting at the indicated operand number.
>> +static bool listContainsReg(MCInst &Inst, unsigned OpNo, unsigned Reg) {
>> + for (unsigned i = OpNo; i < Inst.getNumOperands(); ++i) {
>> + unsigned OpReg = Inst.getOperand(i).getReg();
>> + if (OpReg == Reg)
>> + return true;
>> + }
>> + return false;
>> +}
>> +
>> // FIXME: We would really prefer to have MCInstrInfo (the wrapper around
>> // the ARMInsts array) instead. Getting that here requires awkward
>> // API changes, though. Better way?
>> @@ -3430,6 +3441,11 @@
>> return false;
>> }
>> case ARM::tLDMIA: {
>> + // If we're parsing Thumb2, the .w variant is available and handles
>> + // most cases that are normally illegal for a Thumb1 LDM
>> + // instruction. We'll make the transformation in processInstruction()
>> + // if necessary.
>> + //
>> // Thumb LDM instructions are writeback iff the base register is not
>> // in the register list.
>> unsigned Rn = Inst.getOperand(0).getReg();
>> @@ -3437,14 +3453,15 @@
>> (static_cast<ARMOperand*>(Operands[3])->isToken() &&
>> static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
>> bool listContainsBase;
>> - if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase))
>> + if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) && !isThumbTwo())
>> return Error(Operands[3 + hasWritebackToken]->getStartLoc(),
>> "registers must be in range r0-r7");
>> // If we should have writeback, then there should be a '!' token.
>> - if (!listContainsBase && !hasWritebackToken)
>> + if (!listContainsBase && !hasWritebackToken && !isThumbTwo())
>> return Error(Operands[2]->getStartLoc(),
>> "writeback operator '!' expected");
>
> Does this correctly give an error for an illegal ldm.n?
>
Not yet. Correctly restricting things to 16-bit encodings via ".n" is one of the things that's on the list once I get Thumb2 parsing everything correctly w/o it. These diagnostics will be enabled even in t2 when a .n is present.
-Jim
> -Eli
>
>> - // Likewise, if we should not have writeback, there must not be a '!'
>> + // If we should not have writeback, there must not be a '!'. This is
>> + // true even for the 32-bit wide encodings.
>> if (listContainsBase && hasWritebackToken)
>> return Error(Operands[3]->getStartLoc(),
>> "writeback operator '!' not allowed when base register "
>> @@ -3452,6 +3469,13 @@
>>
>> break;
>> }
>> + case ARM::t2LDMIA_UPD: {
>> + if (listContainsReg(Inst, 3, Inst.getOperand(0).getReg()))
>> + return Error(Operands[4]->getStartLoc(),
>> + "writeback operator '!' not allowed when base register "
>> + "in register list");
>> + break;
>> + }
>> case ARM::tPOP: {
>> bool listContainsBase;
>> if (checkLowRegisterList(Inst, 3, 0, ARM::PC, listContainsBase))
>> @@ -3533,6 +3557,30 @@
>> if (Inst.getOperand(1).getImm() == ARMCC::AL)
>> Inst.setOpcode(ARM::tB);
>> break;
>> + case ARM::tLDMIA: {
>> + // If the register list contains any high registers, or if the writeback
>> + // doesn't match what tLDMIA can do, we need to use the 32-bit encoding
>> + // instead if we're in Thumb2. Otherwise, this should have generated
>> + // an error in validateInstruction().
>> + unsigned Rn = Inst.getOperand(0).getReg();
>> + bool hasWritebackToken =
>> + (static_cast<ARMOperand*>(Operands[3])->isToken() &&
>> + static_cast<ARMOperand*>(Operands[3])->getToken() == "!");
>> + bool listContainsBase;
>> + if (checkLowRegisterList(Inst, 3, Rn, 0, listContainsBase) ||
>> + (!listContainsBase && !hasWritebackToken) ||
>> + (listContainsBase && hasWritebackToken)) {
>> + // 16-bit encoding isn't sufficient. Switch to the 32-bit version.
>> + assert (isThumbTwo());
>> + Inst.setOpcode(hasWritebackToken ? ARM::t2LDMIA_UPD : ARM::t2LDMIA);
>> + // If we're switching to the updating version, we need to insert
>> + // the writeback tied operand.
>> + if (hasWritebackToken)
>> + Inst.insert(Inst.begin(),
>> + MCOperand::CreateReg(Inst.getOperand(0).getReg()));
>> + }
>> + break;
>> + }
>> case ARM::t2IT: {
>> // The mask bits for all but the first condition are represented as
>> // the low bit of the condition code value implies 't'. We currently
>>
>> Modified: llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s?rev=139242&r1=139241&r2=139242&view=diff
>> ==============================================================================
>> --- llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s (original)
>> +++ llvm/trunk/test/MC/ARM/basic-thumb2-instructions.s Wed Sep 7 13:05:34 2011
>> @@ -463,6 +463,44 @@
>>
>>
>> @------------------------------------------------------------------------------
>> +@ LDMIA
>> + at ------------------------------------------------------------------------------
>> + ldmia.w r4, {r4, r5, r8, r9}
>> + ldmia.w r4, {r5, r6}
>> + ldmia.w r5!, {r3, r8}
>> + ldm.w r4, {r4, r5, r8, r9}
>> + ldm.w r4, {r5, r6}
>> + ldm.w r5!, {r3, r8}
>> + ldm.w r5!, {r1, r2}
>> + ldm.w r2, {r1, r2}
>> +
>> + ldmia r4, {r4, r5, r8, r9}
>> + ldmia r4, {r5, r6}
>> + ldmia r5!, {r3, r8}
>> + ldm r4, {r4, r5, r8, r9}
>> + ldm r4, {r5, r6}
>> + ldm r5!, {r3, r8}
>> + ldmfd r5!, {r3, r8}
>> +
>> +@ CHECK: ldm.w r4, {r4, r5, r8, r9} @ encoding: [0x94,0xe8,0x30,0x03]
>> +@ CHECK: ldm.w r4, {r5, r6} @ encoding: [0x94,0xe8,0x60,0x00]
>> +@ CHECK: ldm.w r5!, {r3, r8} @ encoding: [0xb5,0xe8,0x08,0x01]
>> +@ CHECK: ldm.w r4, {r4, r5, r8, r9} @ encoding: [0x94,0xe8,0x30,0x03]
>> +@ CHECK: ldm.w r4, {r5, r6} @ encoding: [0x94,0xe8,0x60,0x00]
>> +@ CHECK: ldm.w r5!, {r3, r8} @ encoding: [0xb5,0xe8,0x08,0x01]
>> +@ CHECK: ldm.w r5!, {r1, r2} @ encoding: [0xb5,0xe8,0x06,0x00]
>> +@ CHECK: ldm.w r2, {r1, r2} @ encoding: [0x92,0xe8,0x06,0x00]
>> +
>> +@ CHECK: ldm.w r4, {r4, r5, r8, r9} @ encoding: [0x94,0xe8,0x30,0x03]
>> +@ CHECK: ldm.w r4, {r5, r6} @ encoding: [0x94,0xe8,0x60,0x00]
>> +@ CHECK: ldm.w r5!, {r3, r8} @ encoding: [0xb5,0xe8,0x08,0x01]
>> +@ CHECK: ldm.w r4, {r4, r5, r8, r9} @ encoding: [0x94,0xe8,0x30,0x03]
>> +@ CHECK: ldm.w r4, {r5, r6} @ encoding: [0x94,0xe8,0x60,0x00]
>> +@ CHECK: ldm.w r5!, {r3, r8} @ encoding: [0xb5,0xe8,0x08,0x01]
>> +@ CHECK: ldm.w r5!, {r3, r8} @ encoding: [0xb5,0xe8,0x08,0x01]
>> +
>> +
>> + at ------------------------------------------------------------------------------
>> @ IT
>> @------------------------------------------------------------------------------
>> @ Test encodings of a few full IT blocks, not just the IT instruction
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>
More information about the llvm-commits
mailing list