aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/PowerPC/MCTargetDesc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/PowerPC/MCTargetDesc')
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp6
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp6
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h8
-rw-r--r--lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp28
4 files changed, 46 insertions, 2 deletions
diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
index 3fa2e09..e01f142 100644
--- a/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
+++ b/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
@@ -34,8 +34,10 @@ static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) {
case PPC::fixup_ppc_nofixup:
return Value;
case PPC::fixup_ppc_brcond14:
+ case PPC::fixup_ppc_brcond14abs:
return Value & 0xfffc;
case PPC::fixup_ppc_br24:
+ case PPC::fixup_ppc_br24abs:
return Value & 0x3fffffc;
case PPC::fixup_ppc_half16:
return Value & 0xffff;
@@ -56,7 +58,9 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
return 2;
case FK_Data_4:
case PPC::fixup_ppc_brcond14:
+ case PPC::fixup_ppc_brcond14abs:
case PPC::fixup_ppc_br24:
+ case PPC::fixup_ppc_br24abs:
return 4;
case FK_Data_8:
return 8;
@@ -93,6 +97,8 @@ public:
// name offset bits flags
{ "fixup_ppc_br24", 6, 24, MCFixupKindInfo::FKF_IsPCRel },
{ "fixup_ppc_brcond14", 16, 14, MCFixupKindInfo::FKF_IsPCRel },
+ { "fixup_ppc_br24abs", 6, 24, 0 },
+ { "fixup_ppc_brcond14abs", 16, 14, 0 },
{ "fixup_ppc_half16", 0, 16, 0 },
{ "fixup_ppc_half16ds", 0, 14, 0 },
{ "fixup_ppc_tlsreg", 0, 0, 0 },
diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
index 69e84a1..f48cb5e 100644
--- a/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
+++ b/lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp
@@ -58,9 +58,11 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
default:
llvm_unreachable("Unimplemented");
case PPC::fixup_ppc_br24:
+ case PPC::fixup_ppc_br24abs:
Type = ELF::R_PPC_REL24;
break;
case PPC::fixup_ppc_brcond14:
+ case PPC::fixup_ppc_brcond14abs:
Type = ELF::R_PPC_REL14;
break;
case PPC::fixup_ppc_half16:
@@ -92,10 +94,10 @@ unsigned PPCELFObjectWriter::getRelocTypeInner(const MCValue &Target,
} else {
switch ((unsigned)Fixup.getKind()) {
default: llvm_unreachable("invalid fixup kind!");
- case PPC::fixup_ppc_br24:
+ case PPC::fixup_ppc_br24abs:
Type = ELF::R_PPC_ADDR24;
break;
- case PPC::fixup_ppc_brcond14:
+ case PPC::fixup_ppc_brcond14abs:
Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
break;
case PPC::fixup_ppc_half16:
diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h b/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
index 3ea59f0..0438c0e 100644
--- a/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
+++ b/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
@@ -25,6 +25,14 @@ enum Fixups {
/// branches.
fixup_ppc_brcond14,
+ /// fixup_ppc_br24abs - 24-bit absolute relocation for direct branches
+ /// like 'ba' and 'bla'.
+ fixup_ppc_br24abs,
+
+ /// fixup_ppc_brcond14abs - 14-bit absolute relocation for conditional
+ /// branches.
+ fixup_ppc_brcond14abs,
+
/// fixup_ppc_half16 - A 16-bit fixup corresponding to lo16(_foo)
/// or ha16(_foo) for instrs like 'li' or 'addis'.
fixup_ppc_half16,
diff --git a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
index 420c01b..1c6adac 100644
--- a/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
+++ b/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
@@ -48,6 +48,10 @@ public:
SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups) const;
+ unsigned getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+ unsigned getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getS16ImmEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo,
@@ -134,6 +138,30 @@ unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo,
return 0;
}
+unsigned PPCMCCodeEmitter::
+getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
+
+ // Add a fixup for the branch target.
+ Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
+ (MCFixupKind)PPC::fixup_ppc_br24abs));
+ return 0;
+}
+
+unsigned PPCMCCodeEmitter::
+getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ const MCOperand &MO = MI.getOperand(OpNo);
+ if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups);
+
+ // Add a fixup for the branch target.
+ Fixups.push_back(MCFixup::Create(0, MO.getExpr(),
+ (MCFixupKind)PPC::fixup_ppc_brcond14abs));
+ return 0;
+}
+
unsigned PPCMCCodeEmitter::getS16ImmEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups) const {
const MCOperand &MO = MI.getOperand(OpNo);