LLVM API Documentation
00001 //===-- MipsOptionRecord.cpp - Abstraction for storing information --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 00010 #include "MipsOptionRecord.h" 00011 #include "MipsELFStreamer.h" 00012 #include "llvm/MC/MCSectionELF.h" 00013 00014 using namespace llvm; 00015 00016 void MipsRegInfoRecord::EmitMipsOptionRecord() { 00017 MCAssembler &MCA = Streamer->getAssembler(); 00018 Triple T(STI.getTargetTriple()); 00019 uint64_t Features = STI.getFeatureBits(); 00020 00021 Streamer->PushSection(); 00022 00023 // We need to distinguish between N64 and the rest because at the moment 00024 // we don't emit .Mips.options for other ELFs other than N64. 00025 // Since .reginfo has the same information as .Mips.options (ODK_REGINFO), 00026 // we can use the same abstraction (MipsRegInfoRecord class) to handle both. 00027 if (Features & Mips::FeatureN64) { 00028 // The EntrySize value of 1 seems strange since the records are neither 00029 // 1-byte long nor fixed length but it matches the value GAS emits. 00030 const MCSectionELF *Sec = 00031 Context.getELFSection(".MIPS.options", ELF::SHT_MIPS_OPTIONS, 00032 ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, 00033 SectionKind::getMetadata(), 1, ""); 00034 MCA.getOrCreateSectionData(*Sec).setAlignment(8); 00035 Streamer->SwitchSection(Sec); 00036 00037 Streamer->EmitIntValue(1, 1); // kind 00038 Streamer->EmitIntValue(40, 1); // size 00039 Streamer->EmitIntValue(0, 2); // section 00040 Streamer->EmitIntValue(0, 4); // info 00041 Streamer->EmitIntValue(ri_gprmask, 4); 00042 Streamer->EmitIntValue(0, 4); // pad 00043 Streamer->EmitIntValue(ri_cprmask[0], 4); 00044 Streamer->EmitIntValue(ri_cprmask[1], 4); 00045 Streamer->EmitIntValue(ri_cprmask[2], 4); 00046 Streamer->EmitIntValue(ri_cprmask[3], 4); 00047 Streamer->EmitIntValue(ri_gp_value, 8); 00048 } else { 00049 const MCSectionELF *Sec = 00050 Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC, 00051 SectionKind::getMetadata(), 24, ""); 00052 MCA.getOrCreateSectionData(*Sec) 00053 .setAlignment(Features & Mips::FeatureN32 ? 8 : 4); 00054 Streamer->SwitchSection(Sec); 00055 00056 Streamer->EmitIntValue(ri_gprmask, 4); 00057 Streamer->EmitIntValue(ri_cprmask[0], 4); 00058 Streamer->EmitIntValue(ri_cprmask[1], 4); 00059 Streamer->EmitIntValue(ri_cprmask[2], 4); 00060 Streamer->EmitIntValue(ri_cprmask[3], 4); 00061 assert((ri_gp_value & 0xffffffff) == ri_gp_value); 00062 Streamer->EmitIntValue(ri_gp_value, 4); 00063 } 00064 00065 Streamer->PopSection(); 00066 } 00067 00068 void MipsRegInfoRecord::SetPhysRegUsed(unsigned Reg, 00069 const MCRegisterInfo *MCRegInfo) { 00070 unsigned Value = 0; 00071 00072 for (MCSubRegIterator SubRegIt(Reg, MCRegInfo, true); SubRegIt.isValid(); 00073 ++SubRegIt) { 00074 unsigned CurrentSubReg = *SubRegIt; 00075 00076 unsigned EncVal = MCRegInfo->getEncodingValue(CurrentSubReg); 00077 Value |= 1 << EncVal; 00078 00079 if (GPR32RegClass->contains(CurrentSubReg) || 00080 GPR64RegClass->contains(CurrentSubReg)) 00081 ri_gprmask |= Value; 00082 else if (FGR32RegClass->contains(CurrentSubReg) || 00083 FGR64RegClass->contains(CurrentSubReg) || 00084 AFGR64RegClass->contains(CurrentSubReg) || 00085 MSA128BRegClass->contains(CurrentSubReg)) 00086 ri_cprmask[1] |= Value; 00087 else if (COP2RegClass->contains(CurrentSubReg)) 00088 ri_cprmask[2] |= Value; 00089 else if (COP3RegClass->contains(CurrentSubReg)) 00090 ri_cprmask[3] |= Value; 00091 } 00092 }