- Fix codegen for pc relative constant (e.g. JT) in thumb mode:

.set PCRELV0, (LJTI1_0_0-(LPCRELL0+4))
LPCRELL0:
        add r1, pc, #PCRELV0
This is not legal since add r1, pc, #c requires the constant be a multiple of 4.
Do the following instead:
        .set PCRELV0, (LJTI1_0_0-(LPCRELL0+4))
LPCRELL0:
        mov r1, #PCRELV0
        add r1, pc

- In thumb mode, it's not possible to use .set generate a pc relative stub
  address. The stub is ARM code which is in a different section from the thumb
  code. Load the value from a constpool instead.
- Some asm printing clean up.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33664 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng
2007-01-30 20:37:08 +00:00
parent 5cbf985dcb
commit c60e76d139
7 changed files with 96 additions and 47 deletions

View File

@@ -122,10 +122,15 @@ namespace {
ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV;
GlobalValue *GV = ACPV->getGV();
std::string Name = Mang->getValueName(GV);
std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
if (!GV)
Name += ACPV->getSymbol();
if (ACPV->isNonLazyPointer()) {
GVNonLazyPtrs.insert(Name);
O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
} else if (ACPV->isStub()) {
FnStubs.insert(Name);
O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
} else
O << Name;
if (ACPV->getPCAdjustment() != 0)
@@ -136,7 +141,7 @@ namespace {
// If the constant pool value is a extern weak symbol, remember to emit
// the weak reference.
if (GV->hasExternalWeakLinkage())
if (GV && GV->hasExternalWeakLinkage())
ExtWeakSymbols.insert(GV);
}
@@ -680,18 +685,29 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
++EmittedInsts;
if (MI->getOpcode() == ARM::CONSTPOOL_ENTRY) {
int Opc = MI->getOpcode();
switch (Opc) {
case ARM::CONSTPOOL_ENTRY:
if (!InCPMode && AFI->isThumbFunction()) {
EmitAlignment(2);
InCPMode = true;
}
} else {
break;
default: {
if (InCPMode && AFI->isThumbFunction()) {
EmitAlignment(1);
InCPMode = false;
}
O << "\t";
}
switch (Opc) {
case ARM::PICADD:
case ARM::PICLD:
case ARM::tPICADD:
break;
default:
O << "\t";
break;
}
}}
// Call the autogenerated instruction printer routines.
printInstruction(MI);