mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	Mips direct object xgot support
This patch provides support for the MIPS relocations:
    *)  R_MIPS_GOT_HI16
    *)  R_MIPS_GOT_LO16
    *)  R_MIPS_CALL_HI16
    *)  R_MIPS_CALL_LO16
These are used for large GOT instruction sequences.
Contributer: Jack Carter
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168471 91177308-0d34-0410-b5e6-96231b3b80d8
			
			
This commit is contained in:
		| @@ -42,6 +42,8 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { | |||||||
|   case Mips::fixup_Mips_GOT_PAGE: |   case Mips::fixup_Mips_GOT_PAGE: | ||||||
|   case Mips::fixup_Mips_GOT_OFST: |   case Mips::fixup_Mips_GOT_OFST: | ||||||
|   case Mips::fixup_Mips_GOT_DISP: |   case Mips::fixup_Mips_GOT_DISP: | ||||||
|  |   case Mips::fixup_Mips_GOT_LO16: | ||||||
|  |   case Mips::fixup_Mips_CALL_LO16: | ||||||
|     break; |     break; | ||||||
|   case Mips::fixup_Mips_PC16: |   case Mips::fixup_Mips_PC16: | ||||||
|     // So far we are only using this type for branches. |     // So far we are only using this type for branches. | ||||||
| @@ -60,6 +62,8 @@ static unsigned adjustFixupValue(unsigned Kind, uint64_t Value) { | |||||||
|     break; |     break; | ||||||
|   case Mips::fixup_Mips_HI16: |   case Mips::fixup_Mips_HI16: | ||||||
|   case Mips::fixup_Mips_GOT_Local: |   case Mips::fixup_Mips_GOT_Local: | ||||||
|  |   case Mips::fixup_Mips_GOT_HI16: | ||||||
|  |   case Mips::fixup_Mips_CALL_HI16: | ||||||
|     // Get the 2nd 16-bits. Also add 1 if bit 15 is 1. |     // Get the 2nd 16-bits. Also add 1 if bit 15 is 1. | ||||||
|     Value = ((Value + 0x8000) >> 16) & 0xffff; |     Value = ((Value + 0x8000) >> 16) & 0xffff; | ||||||
|     break; |     break; | ||||||
| @@ -179,7 +183,11 @@ public: | |||||||
|       { "fixup_Mips_GOT_OFST",     0,     16,   0 }, |       { "fixup_Mips_GOT_OFST",     0,     16,   0 }, | ||||||
|       { "fixup_Mips_GOT_DISP",     0,     16,   0 }, |       { "fixup_Mips_GOT_DISP",     0,     16,   0 }, | ||||||
|       { "fixup_Mips_HIGHER",       0,     16,   0 }, |       { "fixup_Mips_HIGHER",       0,     16,   0 }, | ||||||
|       { "fixup_Mips_HIGHEST",      0,     16,   0 } |       { "fixup_Mips_HIGHEST",      0,     16,   0 }, | ||||||
|  |       { "fixup_Mips_GOT_HI16",     0,     16,   0 }, | ||||||
|  |       { "fixup_Mips_GOT_LO16",     0,     16,   0 }, | ||||||
|  |       { "fixup_Mips_CALL_HI16",    0,     16,   0 }, | ||||||
|  |       { "fixup_Mips_CALL_LO16",    0,     16,   0 } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     if (Kind < FirstTargetFixupKind) |     if (Kind < FirstTargetFixupKind) | ||||||
|   | |||||||
| @@ -179,6 +179,18 @@ unsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, | |||||||
|   case Mips::fixup_Mips_HIGHEST: |   case Mips::fixup_Mips_HIGHEST: | ||||||
|     Type = ELF::R_MIPS_HIGHEST; |     Type = ELF::R_MIPS_HIGHEST; | ||||||
|     break; |     break; | ||||||
|  |   case Mips::fixup_Mips_GOT_HI16: | ||||||
|  |     Type = ELF::R_MIPS_GOT_HI16; | ||||||
|  |     break; | ||||||
|  |   case Mips::fixup_Mips_GOT_LO16: | ||||||
|  |     Type = ELF::R_MIPS_GOT_LO16; | ||||||
|  |     break; | ||||||
|  |   case Mips::fixup_Mips_CALL_HI16: | ||||||
|  |     Type = ELF::R_MIPS_CALL_HI16; | ||||||
|  |     break; | ||||||
|  |   case Mips::fixup_Mips_CALL_LO16: | ||||||
|  |     Type = ELF::R_MIPS_CALL_LO16; | ||||||
|  |     break; | ||||||
|   } |   } | ||||||
|   return Type; |   return Type; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -116,6 +116,18 @@ namespace Mips { | |||||||
|     // resulting in - R_MIPS_HIGHEST |     // resulting in - R_MIPS_HIGHEST | ||||||
|     fixup_Mips_HIGHEST, |     fixup_Mips_HIGHEST, | ||||||
|  |  | ||||||
|  |     // resulting in - R_MIPS_GOT_HI16 | ||||||
|  |     fixup_Mips_GOT_HI16, | ||||||
|  |  | ||||||
|  |     // resulting in - R_MIPS_GOT_LO16 | ||||||
|  |     fixup_Mips_GOT_LO16, | ||||||
|  |  | ||||||
|  |     // resulting in - R_MIPS_CALL_HI16 | ||||||
|  |     fixup_Mips_CALL_HI16, | ||||||
|  |  | ||||||
|  |     // resulting in - R_MIPS_CALL_LO16 | ||||||
|  |     fixup_Mips_CALL_LO16, | ||||||
|  |  | ||||||
|     // Marker |     // Marker | ||||||
|     LastTargetFixupKind, |     LastTargetFixupKind, | ||||||
|     NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind |     NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind | ||||||
|   | |||||||
| @@ -287,6 +287,18 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO, | |||||||
|   case MCSymbolRefExpr::VK_Mips_HIGHEST: |   case MCSymbolRefExpr::VK_Mips_HIGHEST: | ||||||
|     FixupKind = Mips::fixup_Mips_HIGHEST; |     FixupKind = Mips::fixup_Mips_HIGHEST; | ||||||
|     break; |     break; | ||||||
|  |   case MCSymbolRefExpr::VK_Mips_GOT_HI16: | ||||||
|  |     FixupKind = Mips::fixup_Mips_GOT_HI16; | ||||||
|  |     break; | ||||||
|  |   case MCSymbolRefExpr::VK_Mips_GOT_LO16: | ||||||
|  |     FixupKind = Mips::fixup_Mips_GOT_LO16; | ||||||
|  |     break; | ||||||
|  |   case MCSymbolRefExpr::VK_Mips_CALL_HI16: | ||||||
|  |     FixupKind = Mips::fixup_Mips_CALL_HI16; | ||||||
|  |     break; | ||||||
|  |   case MCSymbolRefExpr::VK_Mips_CALL_LO16: | ||||||
|  |     FixupKind = Mips::fixup_Mips_CALL_LO16; | ||||||
|  |     break; | ||||||
|   } // switch |   } // switch | ||||||
|  |  | ||||||
|   Fixups.push_back(MCFixup::Create(0, MO.getExpr(), MCFixupKind(FixupKind))); |   Fixups.push_back(MCFixup::Create(0, MO.getExpr(), MCFixupKind(FixupKind))); | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								test/MC/Mips/xgot.ll
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								test/MC/Mips/xgot.ll
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | ; RUN: llc -filetype=obj -mtriple mipsel-unknown-linux -mxgot %s -o - | elf-dump --dump-section-data  | FileCheck %s | ||||||
|  |  | ||||||
|  | @.str = private unnamed_addr constant [16 x i8] c"ext_1=%d, i=%d\0A\00", align 1 | ||||||
|  | @ext_1 = external global i32 | ||||||
|  |  | ||||||
|  | define void @fill() nounwind { | ||||||
|  | entry: | ||||||
|  |  | ||||||
|  | ; Check that the appropriate relocations were created.  | ||||||
|  | ; For the xgot case we want to see R_MIPS_[GOT|CALL]_[HI|LO]16. | ||||||
|  |  | ||||||
|  | ; R_MIPS_HI16 | ||||||
|  | ; CHECK:     ('r_type', 0x05) | ||||||
|  |  | ||||||
|  | ; R_MIPS_LO16 | ||||||
|  | ; CHECK:     ('r_type', 0x06) | ||||||
|  |  | ||||||
|  | ; R_MIPS_GOT_HI16 | ||||||
|  | ; CHECK:     ('r_type', 0x16) | ||||||
|  |  | ||||||
|  | ; R_MIPS_GOT_LO16 | ||||||
|  | ; CHECK:     ('r_type', 0x17) | ||||||
|  |  | ||||||
|  | ; R_MIPS_GOT | ||||||
|  | ; CHECK:     ('r_type', 0x09) | ||||||
|  |  | ||||||
|  | ; R_MIPS_LO16 | ||||||
|  | ; CHECK:     ('r_type', 0x06) | ||||||
|  |  | ||||||
|  | ; R_MIPS_CALL_HI16 | ||||||
|  | ; CHECK:     ('r_type', 0x1e) | ||||||
|  |  | ||||||
|  | ; R_MIPS_CALL_LO16 | ||||||
|  | ; CHECK:     ('r_type', 0x1f) | ||||||
|  |  | ||||||
|  |   %0 = load i32* @ext_1, align 4 | ||||||
|  |   %call = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([16 x i8]* @.str, i32 0, i32 0), i32 %0) nounwind | ||||||
|  |   ret void | ||||||
|  | } | ||||||
|  |  | ||||||
|  | declare i32 @printf(i8* nocapture, ...) nounwind | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user