parent
672a31c835
commit
0701c5a074
|
@ -647,7 +647,8 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
|
||||||
<< getFunctionNumber() << '_' << JTI << '_' << MO2.getImmedValue();
|
<< getFunctionNumber() << '_' << JTI << '_' << MO2.getImmedValue();
|
||||||
} else
|
} else
|
||||||
printBasicBlockLabel(MBB, false, false);
|
printBasicBlockLabel(MBB, false, false);
|
||||||
O << '\n';
|
if (i != e-1)
|
||||||
|
O << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -352,7 +352,8 @@ unsigned ARMConstantIslands::GetInstSize(MachineInstr *MI) const {
|
||||||
return MI->getOperand(2).getImm();
|
return MI->getOperand(2).getImm();
|
||||||
case ARM::BR_JTr:
|
case ARM::BR_JTr:
|
||||||
case ARM::BR_JTm:
|
case ARM::BR_JTm:
|
||||||
case ARM::BR_JTadd: {
|
case ARM::BR_JTadd:
|
||||||
|
case ARM::tBR_JTr: {
|
||||||
// These are jumptable branches, i.e. a branch followed by an inlined
|
// These are jumptable branches, i.e. a branch followed by an inlined
|
||||||
// jumptable. The size is 4 + 4 * number of entries.
|
// jumptable. The size is 4 + 4 * number of entries.
|
||||||
unsigned JTI = MI->getOperand(MI->getNumOperands()-2).getJumpTableIndex();
|
unsigned JTI = MI->getOperand(MI->getNumOperands()-2).getJumpTableIndex();
|
||||||
|
@ -360,6 +361,13 @@ unsigned ARMConstantIslands::GetInstSize(MachineInstr *MI) const {
|
||||||
MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
|
MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
|
||||||
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
|
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
|
||||||
assert(JTI < JT.size());
|
assert(JTI < JT.size());
|
||||||
|
// Thumb instructions are 2 byte aligned, but JT entries are 4 byte
|
||||||
|
// 4 aligned. The assembler / linker may add 2 byte padding just before
|
||||||
|
// the JT entries. Use + 4 even for tBR_JTr to purposely over-estimate
|
||||||
|
// the size the jumptable.
|
||||||
|
// 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 + 4;
|
return getNumJTEntries(JT, JTI) * 4 + 4;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -56,6 +56,10 @@ class TIt<dag ops, string asm, list<dag> pattern>
|
||||||
class TIx2<dag ops, string asm, list<dag> pattern>
|
class TIx2<dag ops, string asm, list<dag> pattern>
|
||||||
: ThumbI<ops, AddrModeNone, Size4Bytes, asm, "", pattern>;
|
: ThumbI<ops, AddrModeNone, Size4Bytes, asm, "", pattern>;
|
||||||
|
|
||||||
|
// BR_JT instructions
|
||||||
|
class TJTI<dag ops, string asm, list<dag> pattern>
|
||||||
|
: ThumbI<ops, AddrModeNone, SizeSpecial, asm, "", pattern>;
|
||||||
|
|
||||||
def imm_neg_XFORM : SDNodeXForm<imm, [{
|
def imm_neg_XFORM : SDNodeXForm<imm, [{
|
||||||
return CurDAG->getTargetConstant(-(int)N->getValue(), MVT::i32);
|
return CurDAG->getTargetConstant(-(int)N->getValue(), MVT::i32);
|
||||||
}]>;
|
}]>;
|
||||||
|
@ -188,9 +192,14 @@ let isCall = 1, noResults = 1,
|
||||||
[(ARMcall_nolink GPR:$dst)]>;
|
[(ARMcall_nolink GPR:$dst)]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
let isBranch = 1, isTerminator = 1, isBarrier = 1 in
|
let isBranch = 1, isTerminator = 1, isBarrier = 1 in {
|
||||||
def tB : TI<(ops brtarget:$dst), "b $dst", [(br bb:$dst)]>;
|
def tB : TI<(ops brtarget:$dst), "b $dst", [(br bb:$dst)]>;
|
||||||
|
|
||||||
|
def tBR_JTr : TJTI<(ops GPR:$dst, jtblock_operand:$jt, i32imm:$id),
|
||||||
|
"cpy pc, $dst \n\t.align\t2\n$jt",
|
||||||
|
[(ARMbrjt GPR:$dst, tjumptable:$jt, imm:$id)]>;
|
||||||
|
}
|
||||||
|
|
||||||
let isBranch = 1, isTerminator = 1, noResults = 1, isBarrier = 1 in
|
let isBranch = 1, isTerminator = 1, noResults = 1, isBarrier = 1 in
|
||||||
def tBcc : TI<(ops brtarget:$dst, CCOp:$cc), "b$cc $dst",
|
def tBcc : TI<(ops brtarget:$dst, CCOp:$cc), "b$cc $dst",
|
||||||
[(ARMbrcond bb:$dst, imm:$cc)]>;
|
[(ARMbrcond bb:$dst, imm:$cc)]>;
|
||||||
|
@ -477,6 +486,13 @@ def tLEApcrelCall : TI<(ops GPR:$dst, i32imm:$label),
|
||||||
"add $dst, pc, #PCRELV${:uid}")),
|
"add $dst, pc, #PCRELV${:uid}")),
|
||||||
[]>;
|
[]>;
|
||||||
|
|
||||||
|
def tLEApcrelJT : TI<(ops GPR:$dst, i32imm:$label, i32imm:$id),
|
||||||
|
!strconcat(!strconcat(".set PCRELV${:uid}, (${label}_${id:no_hash}-(",
|
||||||
|
"${:private}PCRELL${:uid}+4))\n"),
|
||||||
|
!strconcat("${:private}PCRELL${:uid}:\n\t",
|
||||||
|
"add $dst, pc, #PCRELV${:uid}")),
|
||||||
|
[]>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Non-Instruction Patterns
|
// Non-Instruction Patterns
|
||||||
//
|
//
|
||||||
|
@ -489,6 +505,10 @@ def : ThumbPat<(ARMWrapperCall tglobaladdr :$dst),
|
||||||
def : ThumbPat<(ARMWrapperCall texternalsym:$dst),
|
def : ThumbPat<(ARMWrapperCall texternalsym:$dst),
|
||||||
(tLEApcrelCall texternalsym:$dst)>;
|
(tLEApcrelCall texternalsym:$dst)>;
|
||||||
|
|
||||||
|
// JumpTable
|
||||||
|
def : ThumbPat<(ARMWrapperJT tjumptable:$dst, imm:$id),
|
||||||
|
(tLEApcrelJT tjumptable:$dst, imm:$id)>;
|
||||||
|
|
||||||
// Direct calls
|
// Direct calls
|
||||||
def : ThumbPat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>;
|
def : ThumbPat<(ARMtcall texternalsym:$func), (tBL texternalsym:$func)>;
|
||||||
def : ThumbV5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>;
|
def : ThumbV5Pat<(ARMcall texternalsym:$func), (tBLXi texternalsym:$func)>;
|
||||||
|
|
Loading…
Reference in New Issue