diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index f5ea746743a..76dc349b50c 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -162,16 +162,23 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { switch (MI.getOpcode()) { default: DEBUG(MI.dump()); assert(0 && "Unknown instruction for relocation!"); case PPC::LIS: + case PPC::LIS8: + case PPC::ADDIS8: Reloc = PPC::reloc_absolute_high; // Pointer to symbol break; case PPC::LI: + case PPC::LI8: case PPC::LA: + // Loads. case PPC::LBZ: case PPC::LHA: case PPC::LHZ: case PPC::LWZ: case PPC::LFS: case PPC::LFD: + case PPC::LWZ8: + + // Stores. case PPC::STB: case PPC::STH: case PPC::STW: @@ -179,6 +186,13 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { case PPC::STFD: Reloc = PPC::reloc_absolute_low; break; + + case PPC::LWA: + case PPC::LD: + case PPC::STD: + case PPC::STD_32: + Reloc = PPC::reloc_absolute_low_ix; + break; } } if (MO.isGlobalAddress()) @@ -197,16 +211,19 @@ int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { rv = MCE.getJumpTableEntryAddress(MO.getJumpTableIndex()); unsigned Opcode = MI.getOpcode(); - if (Opcode == PPC::LIS || Opcode == PPC::ADDIS) { + if (Opcode == PPC::LIS || Opcode == PPC::LIS8 || + Opcode == PPC::ADDIS || Opcode == PPC::ADDIS8) { // lis wants hi16(addr) if ((short)rv < 0) rv += 1 << 16; rv >>= 16; - } else if (Opcode == PPC::LWZ || Opcode == PPC::LA || - Opcode == PPC::LI || + } else if (Opcode == PPC::LWZ || Opcode == PPC::LWZ8 || + Opcode == PPC::LA || + Opcode == PPC::LI || Opcode == PPC::LI8 || Opcode == PPC::LFS || Opcode == PPC::LFD) { // These load opcodes want lo16(addr) rv &= 0xffff; } else { + MI.dump(); assert(0 && "Unknown constant pool or jump table using instruction!"); } } else { diff --git a/lib/Target/PowerPC/PPCJITInfo.cpp b/lib/Target/PowerPC/PPCJITInfo.cpp index 98bc4e1fb99..1d4760affaf 100644 --- a/lib/Target/PowerPC/PPCJITInfo.cpp +++ b/lib/Target/PowerPC/PPCJITInfo.cpp @@ -207,7 +207,7 @@ void PPCJITInfo::relocate(void *Function, MachineRelocation *MR, case PPC::reloc_absolute_ptr_high: // Pointer relocations. case PPC::reloc_absolute_ptr_low: case PPC::reloc_absolute_high: // high bits of ref -> low 16 of instr - case PPC::reloc_absolute_low: // low bits of ref -> low 16 of instr + case PPC::reloc_absolute_low: { // low bits of ref -> low 16 of instr ResultPtr += MR->getConstantVal(); // If this is a high-part access, get the high-part. @@ -227,6 +227,16 @@ void PPCJITInfo::relocate(void *Function, MachineRelocation *MR, *RelocPos = LowBits | HighBits; // Slam into low 16-bits break; } + case PPC::reloc_absolute_low_ix: { // low bits of ref -> low 14 of instr + ResultPtr += MR->getConstantVal(); + // Do the addition then mask, so the addition does not overflow the 16-bit + // immediate section of the instruction. + unsigned LowBits = (*RelocPos + ResultPtr) & 0xFFFC; + unsigned HighBits = *RelocPos & 0xFFFF0003; + *RelocPos = LowBits | HighBits; // Slam into low 14-bits. + break; + } + } } } diff --git a/lib/Target/PowerPC/PPCRelocations.h b/lib/Target/PowerPC/PPCRelocations.h index 20d747b06d5..09115e3ebc1 100644 --- a/lib/Target/PowerPC/PPCRelocations.h +++ b/lib/Target/PowerPC/PPCRelocations.h @@ -34,9 +34,13 @@ namespace llvm { reloc_absolute_high, // reloc_absolute_low - Absolute relocation, for the la instruction (which - // is really an addi). Add the low 16-bits of teh specified global + // is really an addi). Add the low 16-bits of the specified global // address into the low 16-bits of the instruction. reloc_absolute_low, + + // reloc_absolute_low_ix - Absolute relocation for the 64-bit load/store + // instruction which have two implicit zero bits. + reloc_absolute_low_ix, // reloc_absolute_ptr_high - Absolute relocation for references to lazy // pointer stubs. In this case, the relocated instruction should be