From 789476240d6b6f8ad9366cadf790a82bd41bb0b3 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 24 Jul 2009 18:20:44 +0000 Subject: [PATCH] Make sure thumb2 jumptable entries are aligned. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76986 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMBaseInstrInfo.cpp | 19 +++++++++++-------- lib/Target/ARM/ARMConstantIslandPass.cpp | 9 +++++---- lib/Target/ARM/ARMInstrThumb2.td | 6 +++--- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index f0f24054a44..b03c308bd2d 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -433,23 +433,27 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { } break; } - case ARMII::Size8Bytes: return 8; // Arm instruction x 2. - case ARMII::Size4Bytes: return 4; // Arm instruction. - case ARMII::Size2Bytes: return 2; // Thumb instruction. + case ARMII::Size8Bytes: return 8; // ARM instruction x 2. + case ARMII::Size4Bytes: return 4; // ARM / Thumb2 instruction. + case ARMII::Size2Bytes: return 2; // Thumb1 instruction. case ARMII::SizeSpecial: { + bool IsThumb1JT = false; switch (MI->getOpcode()) { case ARM::CONSTPOOL_ENTRY: // If this machine instr is a constant pool entry, its size is recorded as // operand #2. return MI->getOperand(2).getImm(); - case ARM::Int_eh_sjlj_setjmp: return 12; + case ARM::Int_eh_sjlj_setjmp: + return 12; + case ARM::tBR_JTr: + IsThumb1JT = true; + // Fallthrough case ARM::BR_JTr: case ARM::BR_JTm: case ARM::BR_JTadd: case ARM::t2BR_JTr: case ARM::t2BR_JTm: - case ARM::t2BR_JTadd: - case ARM::tBR_JTr: { + case ARM::t2BR_JTadd: { // These are jumptable branches, i.e. a branch followed by an inlined // jumptable. The size is 4 + 4 * number of entries. unsigned NumOps = TID.getNumOperands(); @@ -466,8 +470,7 @@ unsigned ARMBaseInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { // FIXME: If we know the size of the function is less than (1 << 16) *2 // bytes, we can use 16-bit entries instead. Then there won't be an // alignment issue. - return getNumJTEntries(JT, JTI) * 4 + - ((MI->getOpcode()==ARM::tBR_JTr) ? 2 : 4); + return getNumJTEntries(JT, JTI) * 4 + (IsThumb1JT ? 2 : 4); } default: // Otherwise, pseudo-instruction sizes are zero. diff --git a/lib/Target/ARM/ARMConstantIslandPass.cpp b/lib/Target/ARM/ARMConstantIslandPass.cpp index b0744d29c60..1f584d4e3ef 100644 --- a/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -788,10 +788,11 @@ void ARMConstantIslands::AdjustBBOffsetsAfter(MachineBasicBlock *BB, } // Thumb1 jump tables require padding. They should be at the end; // following unconditional branches are removed by AnalyzeBranch. - MachineInstr *ThumbJTMI = NULL; - if (prior(MBB->end())->getOpcode() == ARM::tBR_JTr) - ThumbJTMI = prior(MBB->end()); - if (ThumbJTMI) { + MachineInstr *ThumbJTMI = prior(MBB->end()); + if (ThumbJTMI->getOpcode() == ARM::tBR_JTr || + ThumbJTMI->getOpcode() == ARM::t2BR_JTr || + ThumbJTMI->getOpcode() == ARM::t2BR_JTm || + ThumbJTMI->getOpcode() == ARM::t2BR_JTadd) { unsigned newMIOffset = GetOffsetOf(ThumbJTMI); unsigned oldMIOffset = newMIOffset - delta; if (oldMIOffset%4 == 0 && newMIOffset%4 != 0) { diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 8d241c8fef7..548c793819b 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -1082,20 +1082,20 @@ def t2B : T2XI<(outs), (ins brtarget:$target), let isNotDuplicable = 1, isIndirectBranch = 1 in { def t2BR_JTr : T2JTI<(outs), (ins GPR:$target, jtblock_operand:$jt, i32imm:$id), - "mov pc, $target \n$jt", + "mov pc, $target \n\t.align\t2\n$jt", [(ARMbrjt GPR:$target, tjumptable:$jt, imm:$id)]>; def t2BR_JTm : T2JTI<(outs), (ins t2addrmode_so_reg:$target, jtblock_operand:$jt, i32imm:$id), - "ldr pc, $target \n$jt", + "ldr pc, $target \n\t.align\t2\n$jt", [(ARMbrjt (i32 (load t2addrmode_so_reg:$target)), tjumptable:$jt, imm:$id)]>; def t2BR_JTadd : T2JTI<(outs), (ins GPR:$target, GPR:$idx, jtblock_operand:$jt, i32imm:$id), - "add pc, $target, $idx \n$jt", + "add pc, $target, $idx \n\t.align\t2\n$jt", [(ARMbrjt (add GPR:$target, GPR:$idx), tjumptable:$jt, imm:$id)]>; } // isNotDuplicate, isIndirectBranch } // isBranch, isTerminator, isBarrier