diff options
Diffstat (limited to 'llvm/lib')
4 files changed, 21 insertions, 3 deletions
diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp index 76afeb608d1..8292d6b4c55 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -189,7 +189,15 @@ static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, return 0; } break; - + case Mips::fixup_MICROMIPS_PC21_S1: + // Forcing a signed division because Value can be negative. + Value = (int64_t)Value / 2; + // We now check if Value can be encoded as a 21-bit signed immediate. + if (!isInt<21>(Value) && Ctx) { + Ctx->reportError(Fixup.getLoc(), "out of range PC21 fixup"); + return 0; + } + break; } return Value; @@ -343,6 +351,7 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_MICROMIPS_PC26_S1", 0, 26, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_MICROMIPS_PC19_S2", 0, 19, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_MICROMIPS_PC18_S3", 0, 18, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_MICROMIPS_PC21_S1", 0, 21, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_MICROMIPS_CALL16", 0, 16, 0 }, { "fixup_MICROMIPS_GOT_DISP", 0, 16, 0 }, { "fixup_MICROMIPS_GOT_PAGE", 0, 16, 0 }, @@ -411,6 +420,7 @@ getFixupKindInfo(MCFixupKind Kind) const { { "fixup_MICROMIPS_PC26_S1", 6, 26, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_MICROMIPS_PC19_S2",13, 19, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_MICROMIPS_PC18_S3",14, 18, MCFixupKindInfo::FKF_IsPCRel }, + { "fixup_MICROMIPS_PC21_S1",11, 21, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_MICROMIPS_CALL16", 16, 16, 0 }, { "fixup_MICROMIPS_GOT_DISP", 16, 16, 0 }, { "fixup_MICROMIPS_GOT_PAGE", 16, 16, 0 }, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp index a5e63856401..cdad7ce1b73 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -247,6 +247,8 @@ unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, return ELF::R_MICROMIPS_PC19_S2; case Mips::fixup_MICROMIPS_PC18_S3: return ELF::R_MICROMIPS_PC18_S3; + case Mips::fixup_MICROMIPS_PC21_S1: + return ELF::R_MICROMIPS_PC21_S1; case Mips::fixup_MIPS_PC19_S2: return ELF::R_MIPS_PC19_S2; case Mips::fixup_MIPS_PC18_S3: @@ -608,7 +610,7 @@ bool MipsELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, case ELF::R_MICROMIPS_TLS_TPREL_LO16: case ELF::R_MICROMIPS_GPREL7_S2: case ELF::R_MICROMIPS_PC23_S2: - case ELF::R_MICROMIPS_PC21_S2: + case ELF::R_MICROMIPS_PC21_S1: case ELF::R_MICROMIPS_PC26_S1: case ELF::R_MICROMIPS_PC18_S3: case ELF::R_MICROMIPS_PC19_S2: diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h index 1a15a648004..b4d8e949465 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h @@ -176,6 +176,9 @@ namespace Mips { // resulting in - R_MICROMIPS_PC18_S3 fixup_MICROMIPS_PC18_S3, + // resulting in - R_MICROMIPS_PC21_S1 + fixup_MICROMIPS_PC21_S1, + // resulting in - R_MICROMIPS_CALL16 fixup_MICROMIPS_CALL16, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp index 7e0fc30dc48..3806b68a4be 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsMCCodeEmitter.cpp @@ -384,7 +384,10 @@ getBranchTarget21OpValueMM(const MCInst &MI, unsigned OpNo, assert(MO.isExpr() && "getBranchTarget21OpValueMM expects only expressions or immediates"); - // TODO: Push fixup. + const MCExpr *FixupExpression = MCBinaryExpr::createAdd( + MO.getExpr(), MCConstantExpr::create(-4, Ctx), Ctx); + Fixups.push_back(MCFixup::create(0, FixupExpression, + MCFixupKind(Mips::fixup_MICROMIPS_PC21_S1))); return 0; } |