mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-16 11:30:51 +00:00
6816d66d99
This abstraction allows us to support the various records that can be placed in the .MIPS.options section in the future. We currently use it to record register usage information (the ODK_REGINFO record in our ELF64 spec). Each .MIPS.options record should subclass MipsOptionRecord and provide an implementation of EmitMipsOptionRecord. Patch by Matheus Almeida and Toma Tabacu git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@213522 91177308-0d34-0410-b5e6-96231b3b80d8
93 lines
3.5 KiB
C++
93 lines
3.5 KiB
C++
//===-- MipsOptionRecord.cpp - Abstraction for storing information --------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "MipsOptionRecord.h"
|
|
#include "MipsELFStreamer.h"
|
|
#include "llvm/MC/MCSectionELF.h"
|
|
|
|
using namespace llvm;
|
|
|
|
void MipsRegInfoRecord::EmitMipsOptionRecord() {
|
|
MCAssembler &MCA = Streamer->getAssembler();
|
|
Triple T(STI.getTargetTriple());
|
|
uint64_t Features = STI.getFeatureBits();
|
|
|
|
Streamer->PushSection();
|
|
|
|
// We need to distinguish between N64 and the rest because at the moment
|
|
// we don't emit .Mips.options for other ELFs other than N64.
|
|
// Since .reginfo has the same information as .Mips.options (ODK_REGINFO),
|
|
// we can use the same abstraction (MipsRegInfoRecord class) to handle both.
|
|
if (Features & Mips::FeatureN64) {
|
|
// The EntrySize value of 1 seems strange since the records are neither
|
|
// 1-byte long nor fixed length but it matches the value GAS emits.
|
|
const MCSectionELF *Sec =
|
|
Context.getELFSection(".MIPS.options", ELF::SHT_MIPS_OPTIONS,
|
|
ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP,
|
|
SectionKind::getMetadata(), 1, "");
|
|
MCA.getOrCreateSectionData(*Sec).setAlignment(8);
|
|
Streamer->SwitchSection(Sec);
|
|
|
|
Streamer->EmitIntValue(1, 1); // kind
|
|
Streamer->EmitIntValue(40, 1); // size
|
|
Streamer->EmitIntValue(0, 2); // section
|
|
Streamer->EmitIntValue(0, 4); // info
|
|
Streamer->EmitIntValue(ri_gprmask, 4);
|
|
Streamer->EmitIntValue(0, 4); // pad
|
|
Streamer->EmitIntValue(ri_cprmask[0], 4);
|
|
Streamer->EmitIntValue(ri_cprmask[1], 4);
|
|
Streamer->EmitIntValue(ri_cprmask[2], 4);
|
|
Streamer->EmitIntValue(ri_cprmask[3], 4);
|
|
Streamer->EmitIntValue(ri_gp_value, 8);
|
|
} else {
|
|
const MCSectionELF *Sec =
|
|
Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO, ELF::SHF_ALLOC,
|
|
SectionKind::getMetadata(), 24, "");
|
|
MCA.getOrCreateSectionData(*Sec)
|
|
.setAlignment(Features & Mips::FeatureN32 ? 8 : 4);
|
|
Streamer->SwitchSection(Sec);
|
|
|
|
Streamer->EmitIntValue(ri_gprmask, 4);
|
|
Streamer->EmitIntValue(ri_cprmask[0], 4);
|
|
Streamer->EmitIntValue(ri_cprmask[1], 4);
|
|
Streamer->EmitIntValue(ri_cprmask[2], 4);
|
|
Streamer->EmitIntValue(ri_cprmask[3], 4);
|
|
assert((ri_gp_value & 0xffffffff) == ri_gp_value);
|
|
Streamer->EmitIntValue(ri_gp_value, 4);
|
|
}
|
|
|
|
Streamer->PopSection();
|
|
}
|
|
|
|
void MipsRegInfoRecord::SetPhysRegUsed(unsigned Reg,
|
|
const MCRegisterInfo *MCRegInfo) {
|
|
unsigned Value = 0;
|
|
|
|
for (MCSubRegIterator SubRegIt(Reg, MCRegInfo, true); SubRegIt.isValid();
|
|
++SubRegIt) {
|
|
unsigned CurrentSubReg = *SubRegIt;
|
|
|
|
unsigned EncVal = MCRegInfo->getEncodingValue(CurrentSubReg);
|
|
Value |= 1 << EncVal;
|
|
|
|
if (GPR32RegClass->contains(CurrentSubReg) ||
|
|
GPR64RegClass->contains(CurrentSubReg))
|
|
ri_gprmask |= Value;
|
|
else if (FGR32RegClass->contains(CurrentSubReg) ||
|
|
FGR64RegClass->contains(CurrentSubReg) ||
|
|
AFGR64RegClass->contains(CurrentSubReg) ||
|
|
MSA128BRegClass->contains(CurrentSubReg))
|
|
ri_cprmask[1] |= Value;
|
|
else if (COP2RegClass->contains(CurrentSubReg))
|
|
ri_cprmask[2] |= Value;
|
|
else if (COP3RegClass->contains(CurrentSubReg))
|
|
ri_cprmask[3] |= Value;
|
|
}
|
|
}
|