Index: llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp =================================================================== --- llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ llvm/lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -41,11 +41,14 @@ case Sparc::fixup_sparc_br19: return (Value >> 2) & 0x7ffff; - case Sparc::fixup_sparc_br16_2: - return (Value >> 2) & 0xc000; - - case Sparc::fixup_sparc_br16_14: - return (Value >> 2) & 0x3fff; + case Sparc::fixup_sparc_br16: { + // A.3 Branch on Integer Register with Prediction (BPr) + // Inst{21-20} = d16hi; + // Inst{13-0} = d16lo; + unsigned d16hi = (Value >> 16) & 0x3; + unsigned d16lo = (Value >> 2) & 0x3fff; + return (d16hi << 20) | d16lo; + } case Sparc::fixup_sparc_hix22: return (~Value >> 10) & 0x3fffff; @@ -160,97 +163,95 @@ const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override { const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = { - // name offset bits flags - { "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_br16_2", 10, 2, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_br16_14", 18, 14, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_13", 19, 13, 0 }, - { "fixup_sparc_hi22", 10, 22, 0 }, - { "fixup_sparc_lo10", 22, 10, 0 }, - { "fixup_sparc_h44", 10, 22, 0 }, - { "fixup_sparc_m44", 22, 10, 0 }, - { "fixup_sparc_l44", 20, 12, 0 }, - { "fixup_sparc_hh", 10, 22, 0 }, - { "fixup_sparc_hm", 22, 10, 0 }, - { "fixup_sparc_lm", 10, 22, 0 }, - { "fixup_sparc_pc22", 10, 22, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_got22", 10, 22, 0 }, - { "fixup_sparc_got10", 22, 10, 0 }, - { "fixup_sparc_got13", 19, 13, 0 }, - { "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_tls_gd_hi22", 10, 22, 0 }, - { "fixup_sparc_tls_gd_lo10", 22, 10, 0 }, - { "fixup_sparc_tls_gd_add", 0, 0, 0 }, - { "fixup_sparc_tls_gd_call", 0, 0, 0 }, - { "fixup_sparc_tls_ldm_hi22", 10, 22, 0 }, - { "fixup_sparc_tls_ldm_lo10", 22, 10, 0 }, - { "fixup_sparc_tls_ldm_add", 0, 0, 0 }, - { "fixup_sparc_tls_ldm_call", 0, 0, 0 }, - { "fixup_sparc_tls_ldo_hix22", 10, 22, 0 }, - { "fixup_sparc_tls_ldo_lox10", 22, 10, 0 }, - { "fixup_sparc_tls_ldo_add", 0, 0, 0 }, - { "fixup_sparc_tls_ie_hi22", 10, 22, 0 }, - { "fixup_sparc_tls_ie_lo10", 22, 10, 0 }, - { "fixup_sparc_tls_ie_ld", 0, 0, 0 }, - { "fixup_sparc_tls_ie_ldx", 0, 0, 0 }, - { "fixup_sparc_tls_ie_add", 0, 0, 0 }, - { "fixup_sparc_tls_le_hix22", 0, 0, 0 }, - { "fixup_sparc_tls_le_lox10", 0, 0, 0 }, - { "fixup_sparc_hix22", 10, 22, 0 }, - { "fixup_sparc_lox10", 19, 13, 0 }, - { "fixup_sparc_gotdata_hix22", 0, 0, 0 }, - { "fixup_sparc_gotdata_lox10", 0, 0, 0 }, - { "fixup_sparc_gotdata_op", 0, 0, 0 }, + // name offset bits flags + {"fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_br16", 0, 32, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_13", 19, 13, 0}, + {"fixup_sparc_hi22", 10, 22, 0}, + {"fixup_sparc_lo10", 22, 10, 0}, + {"fixup_sparc_h44", 10, 22, 0}, + {"fixup_sparc_m44", 22, 10, 0}, + {"fixup_sparc_l44", 20, 12, 0}, + {"fixup_sparc_hh", 10, 22, 0}, + {"fixup_sparc_hm", 22, 10, 0}, + {"fixup_sparc_lm", 10, 22, 0}, + {"fixup_sparc_pc22", 10, 22, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_got22", 10, 22, 0}, + {"fixup_sparc_got10", 22, 10, 0}, + {"fixup_sparc_got13", 19, 13, 0}, + {"fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_tls_gd_hi22", 10, 22, 0}, + {"fixup_sparc_tls_gd_lo10", 22, 10, 0}, + {"fixup_sparc_tls_gd_add", 0, 0, 0}, + {"fixup_sparc_tls_gd_call", 0, 0, 0}, + {"fixup_sparc_tls_ldm_hi22", 10, 22, 0}, + {"fixup_sparc_tls_ldm_lo10", 22, 10, 0}, + {"fixup_sparc_tls_ldm_add", 0, 0, 0}, + {"fixup_sparc_tls_ldm_call", 0, 0, 0}, + {"fixup_sparc_tls_ldo_hix22", 10, 22, 0}, + {"fixup_sparc_tls_ldo_lox10", 22, 10, 0}, + {"fixup_sparc_tls_ldo_add", 0, 0, 0}, + {"fixup_sparc_tls_ie_hi22", 10, 22, 0}, + {"fixup_sparc_tls_ie_lo10", 22, 10, 0}, + {"fixup_sparc_tls_ie_ld", 0, 0, 0}, + {"fixup_sparc_tls_ie_ldx", 0, 0, 0}, + {"fixup_sparc_tls_ie_add", 0, 0, 0}, + {"fixup_sparc_tls_le_hix22", 0, 0, 0}, + {"fixup_sparc_tls_le_lox10", 0, 0, 0}, + {"fixup_sparc_hix22", 10, 22, 0}, + {"fixup_sparc_lox10", 19, 13, 0}, + {"fixup_sparc_gotdata_hix22", 0, 0, 0}, + {"fixup_sparc_gotdata_lox10", 0, 0, 0}, + {"fixup_sparc_gotdata_op", 0, 0, 0}, }; const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = { - // name offset bits flags - { "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_br16_2", 20, 2, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_br16_14", 0, 14, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_13", 0, 13, 0 }, - { "fixup_sparc_hi22", 0, 22, 0 }, - { "fixup_sparc_lo10", 0, 10, 0 }, - { "fixup_sparc_h44", 0, 22, 0 }, - { "fixup_sparc_m44", 0, 10, 0 }, - { "fixup_sparc_l44", 0, 12, 0 }, - { "fixup_sparc_hh", 0, 22, 0 }, - { "fixup_sparc_hm", 0, 10, 0 }, - { "fixup_sparc_lm", 0, 22, 0 }, - { "fixup_sparc_pc22", 0, 22, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_pc10", 0, 10, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_got22", 0, 22, 0 }, - { "fixup_sparc_got10", 0, 10, 0 }, - { "fixup_sparc_got13", 0, 13, 0 }, - { "fixup_sparc_wplt30", 0, 30, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_sparc_tls_gd_hi22", 0, 22, 0 }, - { "fixup_sparc_tls_gd_lo10", 0, 10, 0 }, - { "fixup_sparc_tls_gd_add", 0, 0, 0 }, - { "fixup_sparc_tls_gd_call", 0, 0, 0 }, - { "fixup_sparc_tls_ldm_hi22", 0, 22, 0 }, - { "fixup_sparc_tls_ldm_lo10", 0, 10, 0 }, - { "fixup_sparc_tls_ldm_add", 0, 0, 0 }, - { "fixup_sparc_tls_ldm_call", 0, 0, 0 }, - { "fixup_sparc_tls_ldo_hix22", 0, 22, 0 }, - { "fixup_sparc_tls_ldo_lox10", 0, 10, 0 }, - { "fixup_sparc_tls_ldo_add", 0, 0, 0 }, - { "fixup_sparc_tls_ie_hi22", 0, 22, 0 }, - { "fixup_sparc_tls_ie_lo10", 0, 10, 0 }, - { "fixup_sparc_tls_ie_ld", 0, 0, 0 }, - { "fixup_sparc_tls_ie_ldx", 0, 0, 0 }, - { "fixup_sparc_tls_ie_add", 0, 0, 0 }, - { "fixup_sparc_tls_le_hix22", 0, 0, 0 }, - { "fixup_sparc_tls_le_lox10", 0, 0, 0 }, - { "fixup_sparc_hix22", 0, 22, 0 }, - { "fixup_sparc_lox10", 0, 13, 0 }, - { "fixup_sparc_gotdata_hix22", 0, 0, 0 }, - { "fixup_sparc_gotdata_lox10", 0, 0, 0 }, - { "fixup_sparc_gotdata_op", 0, 0, 0 }, + // name offset bits flags + {"fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_br16", 32, 0, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_13", 0, 13, 0}, + {"fixup_sparc_hi22", 0, 22, 0}, + {"fixup_sparc_lo10", 0, 10, 0}, + {"fixup_sparc_h44", 0, 22, 0}, + {"fixup_sparc_m44", 0, 10, 0}, + {"fixup_sparc_l44", 0, 12, 0}, + {"fixup_sparc_hh", 0, 22, 0}, + {"fixup_sparc_hm", 0, 10, 0}, + {"fixup_sparc_lm", 0, 22, 0}, + {"fixup_sparc_pc22", 0, 22, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_pc10", 0, 10, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_got22", 0, 22, 0}, + {"fixup_sparc_got10", 0, 10, 0}, + {"fixup_sparc_got13", 0, 13, 0}, + {"fixup_sparc_wplt30", 0, 30, MCFixupKindInfo::FKF_IsPCRel}, + {"fixup_sparc_tls_gd_hi22", 0, 22, 0}, + {"fixup_sparc_tls_gd_lo10", 0, 10, 0}, + {"fixup_sparc_tls_gd_add", 0, 0, 0}, + {"fixup_sparc_tls_gd_call", 0, 0, 0}, + {"fixup_sparc_tls_ldm_hi22", 0, 22, 0}, + {"fixup_sparc_tls_ldm_lo10", 0, 10, 0}, + {"fixup_sparc_tls_ldm_add", 0, 0, 0}, + {"fixup_sparc_tls_ldm_call", 0, 0, 0}, + {"fixup_sparc_tls_ldo_hix22", 0, 22, 0}, + {"fixup_sparc_tls_ldo_lox10", 0, 10, 0}, + {"fixup_sparc_tls_ldo_add", 0, 0, 0}, + {"fixup_sparc_tls_ie_hi22", 0, 22, 0}, + {"fixup_sparc_tls_ie_lo10", 0, 10, 0}, + {"fixup_sparc_tls_ie_ld", 0, 0, 0}, + {"fixup_sparc_tls_ie_ldx", 0, 0, 0}, + {"fixup_sparc_tls_ie_add", 0, 0, 0}, + {"fixup_sparc_tls_le_hix22", 0, 0, 0}, + {"fixup_sparc_tls_le_lox10", 0, 0, 0}, + {"fixup_sparc_hix22", 0, 22, 0}, + {"fixup_sparc_lox10", 0, 13, 0}, + {"fixup_sparc_gotdata_hix22", 0, 0, 0}, + {"fixup_sparc_gotdata_lox10", 0, 0, 0}, + {"fixup_sparc_gotdata_op", 0, 0, 0}, }; // Fixup kinds from .reloc directive are like R_SPARC_NONE. They do @@ -345,9 +346,16 @@ if (Fixup.getKind() >= FirstLiteralRelocationKind) return; + MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind()); Value = adjustFixupValue(Fixup.getKind(), Value); if (!Value) return; // Doesn't change encoding. + // Shift the value into position. + if (Endian == support::little) + Value <<= Info.TargetOffset; + else + Value <<= 32 - Info.TargetOffset - Info.TargetSize; + unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind()); unsigned Offset = Fixup.getOffset(); // For each byte of the fragment that the fixup touches, mask in the bits Index: llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp =================================================================== --- llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +++ llvm/lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp @@ -62,6 +62,8 @@ case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP30; case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP22; case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19; + case Sparc::fixup_sparc_br16: + return ELF::R_SPARC_WDISP16; case Sparc::fixup_sparc_pc22: return ELF::R_SPARC_PC22; case Sparc::fixup_sparc_pc10: return ELF::R_SPARC_PC10; case Sparc::fixup_sparc_wplt30: return ELF::R_SPARC_WPLT30; Index: llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h =================================================================== --- llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h +++ llvm/lib/Target/Sparc/MCTargetDesc/SparcFixupKinds.h @@ -13,104 +13,103 @@ namespace llvm { namespace Sparc { - enum Fixups { - // fixup_sparc_call30 - 30-bit PC relative relocation for call - fixup_sparc_call30 = FirstTargetFixupKind, - - /// fixup_sparc_br22 - 22-bit PC relative relocation for - /// branches - fixup_sparc_br22, - - /// fixup_sparc_br19 - 19-bit PC relative relocation for - /// branches on icc/xcc - fixup_sparc_br19, - - /// fixup_sparc_bpr - 16-bit fixup for bpr - fixup_sparc_br16_2, - fixup_sparc_br16_14, - - /// fixup_sparc_13 - 13-bit fixup - fixup_sparc_13, - - /// fixup_sparc_hi22 - 22-bit fixup corresponding to %hi(foo) - /// for sethi - fixup_sparc_hi22, - - /// fixup_sparc_lo10 - 10-bit fixup corresponding to %lo(foo) - fixup_sparc_lo10, - - /// fixup_sparc_h44 - 22-bit fixup corresponding to %h44(foo) - fixup_sparc_h44, - - /// fixup_sparc_m44 - 10-bit fixup corresponding to %m44(foo) - fixup_sparc_m44, - - /// fixup_sparc_l44 - 12-bit fixup corresponding to %l44(foo) - fixup_sparc_l44, - - /// fixup_sparc_hh - 22-bit fixup corresponding to %hh(foo) - fixup_sparc_hh, - - /// fixup_sparc_hm - 10-bit fixup corresponding to %hm(foo) - fixup_sparc_hm, - - /// fixup_sparc_lm - 22-bit fixup corresponding to %lm(foo) - fixup_sparc_lm, - - /// fixup_sparc_pc22 - 22-bit fixup corresponding to %pc22(foo) - fixup_sparc_pc22, - - /// fixup_sparc_pc10 - 10-bit fixup corresponding to %pc10(foo) - fixup_sparc_pc10, - - /// fixup_sparc_got22 - 22-bit fixup corresponding to %got22(foo) - fixup_sparc_got22, - - /// fixup_sparc_got10 - 10-bit fixup corresponding to %got10(foo) - fixup_sparc_got10, - - /// fixup_sparc_got13 - 13-bit fixup corresponding to %got13(foo) - fixup_sparc_got13, - - /// fixup_sparc_wplt30 - fixup_sparc_wplt30, - - /// fixups for Thread Local Storage - fixup_sparc_tls_gd_hi22, - fixup_sparc_tls_gd_lo10, - fixup_sparc_tls_gd_add, - fixup_sparc_tls_gd_call, - fixup_sparc_tls_ldm_hi22, - fixup_sparc_tls_ldm_lo10, - fixup_sparc_tls_ldm_add, - fixup_sparc_tls_ldm_call, - fixup_sparc_tls_ldo_hix22, - fixup_sparc_tls_ldo_lox10, - fixup_sparc_tls_ldo_add, - fixup_sparc_tls_ie_hi22, - fixup_sparc_tls_ie_lo10, - fixup_sparc_tls_ie_ld, - fixup_sparc_tls_ie_ldx, - fixup_sparc_tls_ie_add, - fixup_sparc_tls_le_hix22, - fixup_sparc_tls_le_lox10, - - /// 22-bit fixup corresponding to %hix(foo) - fixup_sparc_hix22, - /// 13-bit fixup corresponding to %lox(foo) - fixup_sparc_lox10, - - /// 22-bit fixup corresponding to %gdop_hix22(foo) - fixup_sparc_gotdata_hix22, - /// 13-bit fixup corresponding to %gdop_lox10(foo) - fixup_sparc_gotdata_lox10, - /// 32-bit fixup corresponding to %gdop(foo) - fixup_sparc_gotdata_op, - - // Marker - LastTargetFixupKind, - NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind - }; + enum Fixups { + // fixup_sparc_call30 - 30-bit PC relative relocation for call + fixup_sparc_call30 = FirstTargetFixupKind, + + /// fixup_sparc_br22 - 22-bit PC relative relocation for + /// branches + fixup_sparc_br22, + + /// fixup_sparc_br19 - 19-bit PC relative relocation for + /// branches on icc/xcc + fixup_sparc_br19, + + /// fixup_sparc_bpr - 16-bit fixup for bpr + fixup_sparc_br16, + + /// fixup_sparc_13 - 13-bit fixup + fixup_sparc_13, + + /// fixup_sparc_hi22 - 22-bit fixup corresponding to %hi(foo) + /// for sethi + fixup_sparc_hi22, + + /// fixup_sparc_lo10 - 10-bit fixup corresponding to %lo(foo) + fixup_sparc_lo10, + + /// fixup_sparc_h44 - 22-bit fixup corresponding to %h44(foo) + fixup_sparc_h44, + + /// fixup_sparc_m44 - 10-bit fixup corresponding to %m44(foo) + fixup_sparc_m44, + + /// fixup_sparc_l44 - 12-bit fixup corresponding to %l44(foo) + fixup_sparc_l44, + + /// fixup_sparc_hh - 22-bit fixup corresponding to %hh(foo) + fixup_sparc_hh, + + /// fixup_sparc_hm - 10-bit fixup corresponding to %hm(foo) + fixup_sparc_hm, + + /// fixup_sparc_lm - 22-bit fixup corresponding to %lm(foo) + fixup_sparc_lm, + + /// fixup_sparc_pc22 - 22-bit fixup corresponding to %pc22(foo) + fixup_sparc_pc22, + + /// fixup_sparc_pc10 - 10-bit fixup corresponding to %pc10(foo) + fixup_sparc_pc10, + + /// fixup_sparc_got22 - 22-bit fixup corresponding to %got22(foo) + fixup_sparc_got22, + + /// fixup_sparc_got10 - 10-bit fixup corresponding to %got10(foo) + fixup_sparc_got10, + + /// fixup_sparc_got13 - 13-bit fixup corresponding to %got13(foo) + fixup_sparc_got13, + + /// fixup_sparc_wplt30 + fixup_sparc_wplt30, + + /// fixups for Thread Local Storage + fixup_sparc_tls_gd_hi22, + fixup_sparc_tls_gd_lo10, + fixup_sparc_tls_gd_add, + fixup_sparc_tls_gd_call, + fixup_sparc_tls_ldm_hi22, + fixup_sparc_tls_ldm_lo10, + fixup_sparc_tls_ldm_add, + fixup_sparc_tls_ldm_call, + fixup_sparc_tls_ldo_hix22, + fixup_sparc_tls_ldo_lox10, + fixup_sparc_tls_ldo_add, + fixup_sparc_tls_ie_hi22, + fixup_sparc_tls_ie_lo10, + fixup_sparc_tls_ie_ld, + fixup_sparc_tls_ie_ldx, + fixup_sparc_tls_ie_add, + fixup_sparc_tls_le_hix22, + fixup_sparc_tls_le_lox10, + + /// 22-bit fixup corresponding to %hix(foo) + fixup_sparc_hix22, + /// 13-bit fixup corresponding to %lox(foo) + fixup_sparc_lox10, + + /// 22-bit fixup corresponding to %gdop_hix22(foo) + fixup_sparc_gotdata_hix22, + /// 13-bit fixup corresponding to %gdop_lox10(foo) + fixup_sparc_gotdata_lox10, + /// 32-bit fixup corresponding to %gdop(foo) + fixup_sparc_gotdata_op, + + // Marker + LastTargetFixupKind, + NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind + }; } } Index: llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp =================================================================== --- llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp +++ llvm/lib/Target/Sparc/MCTargetDesc/SparcMCCodeEmitter.cpp @@ -235,10 +235,8 @@ if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI); - Fixups.push_back(MCFixup::create(0, MO.getExpr(), - (MCFixupKind)Sparc::fixup_sparc_br16_2)); - Fixups.push_back(MCFixup::create(0, MO.getExpr(), - (MCFixupKind)Sparc::fixup_sparc_br16_14)); + Fixups.push_back( + MCFixup::create(0, MO.getExpr(), (MCFixupKind)Sparc::fixup_sparc_br16)); return 0; } Index: llvm/test/MC/Sparc/sparc64-bpr-offset.s =================================================================== --- /dev/null +++ llvm/test/MC/Sparc/sparc64-bpr-offset.s @@ -0,0 +1,31 @@ +! RUN: llvm-mc -arch=sparcv9 -filetype=obj %s | llvm-objdump -d - | FileCheck %s --check-prefix=BIN + + !! SPARCv9/SPARC64 BPr branches have different offset encoding for the others, + !! make sure that our offset bits don't trample on other fields. + !! This is particularly important with backwards branches. + + ! BIN: 0: 02 c8 40 01 brz %g1, 1 + ! BIN: 4: 04 c8 40 01 brlez %g1, 1 + ! BIN: 8: 06 c8 40 01 brlz %g1, 1 + ! BIN: c: 0a c8 40 01 brnz %g1, 1 + ! BIN: 10: 0c c8 40 01 brgz %g1, 1 + ! BIN: 14: 0e c8 40 01 brgez %g1, 1 + brz %g1, .+4 + brlez %g1, .+4 + brlz %g1, .+4 + brnz %g1, .+4 + brgz %g1, .+4 + brgez %g1, .+4 + + ! BIN: 18: 02 f8 7f ff brz %g1, 65535 + ! BIN: 1c: 04 f8 7f ff brlez %g1, 65535 + ! BIN: 20: 06 f8 7f ff brlz %g1, 65535 + ! BIN: 24: 0a f8 7f ff brnz %g1, 65535 + ! BIN: 28: 0c f8 7f ff brgz %g1, 65535 + ! BIN: 2c: 0e f8 7f ff brgez %g1, 65535 + brz %g1, .-4 + brlez %g1, .-4 + brlz %g1, .-4 + brnz %g1, .-4 + brgz %g1, .-4 + brgez %g1, .-4 Index: llvm/test/MC/Sparc/sparc64-ctrl-instructions.s =================================================================== --- llvm/test/MC/Sparc/sparc64-ctrl-instructions.s +++ llvm/test/MC/Sparc/sparc64-ctrl-instructions.s @@ -1150,24 +1150,18 @@ fbne,a,pn %fcc3, .BB0 - ! CHECK: brz %g1, .BB0 ! encoding: [0x02,0b11AA1000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 - ! CHECK: brlez %g1, .BB0 ! encoding: [0x04,0b11AA1000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 - ! CHECK: brlz %g1, .BB0 ! encoding: [0x06,0b11AA1000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 - ! CHECK: brnz %g1, .BB0 ! encoding: [0x0a,0b11AA1000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 - ! CHECK: brgz %g1, .BB0 ! encoding: [0x0c,0b11AA1000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 - ! CHECK: brgez %g1, .BB0 ! encoding: [0x0e,0b11AA1000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 + ! CHECK: brz %g1, .BB0 ! encoding: [0x02'A',0xc8'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 + ! CHECK: brlez %g1, .BB0 ! encoding: [0x04'A',0xc8'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 + ! CHECK: brlz %g1, .BB0 ! encoding: [0x06'A',0xc8'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 + ! CHECK: brnz %g1, .BB0 ! encoding: [0x0a'A',0xc8'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 + ! CHECK: brgz %g1, .BB0 ! encoding: [0x0c'A',0xc8'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 + ! CHECK: brgez %g1, .BB0 ! encoding: [0x0e'A',0xc8'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 brz %g1, .BB0 brlez %g1, .BB0 @@ -1176,29 +1170,24 @@ brgz %g1, .BB0 brgez %g1, .BB0 - ! CHECK: brz %g1, .BB0 ! encoding: [0x02,0b11AA1000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 + ! CHECK: brz %g1, .BB0 ! encoding: [0x02'A',0xc8'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 brz,pt %g1, .BB0 - ! CHECK: brz,a %g1, .BB0 ! encoding: [0x22,0b11AA1000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 + ! CHECK: brz,a %g1, .BB0 ! encoding: [0x22'A',0xc8'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 brz,a %g1, .BB0 - ! CHECK: brz,a %g1, .BB0 ! encoding: [0x22,0b11AA1000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 + ! CHECK: brz,a %g1, .BB0 ! encoding: [0x22'A',0xc8'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 brz,a,pt %g1, .BB0 - ! CHECK: brz,pn %g1, .BB0 ! encoding: [0x02,0b11AA0000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 + ! CHECK: brz,pn %g1, .BB0 ! encoding: [0x02'A',0xc0'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 brz,pn %g1, .BB0 - ! CHECK: brz,a,pn %g1, .BB0 ! encoding: [0x22,0b11AA0000,0b01BBBBBB,B] - ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16_2 - ! CHECK-NEXT: ! fixup B - offset: 0, value: .BB0, kind: fixup_sparc_br16_14 + ! CHECK: brz,a,pn %g1, .BB0 ! encoding: [0x22'A',0xc0'A',0x40'A',A] + ! CHECK-NEXT: ! fixup A - offset: 0, value: .BB0, kind: fixup_sparc_br16 brz,a,pn %g1, .BB0 ! CHECK: movrz %g1, %g2, %g3 ! encoding: [0x87,0x78,0x44,0x02]