Home | History | Annotate | Line # | Download | only in MCTargetDesc
      1 //===- MipsOptionRecord.cpp - Abstraction for storing information ---------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #include "MipsOptionRecord.h"
     10 #include "MipsABIInfo.h"
     11 #include "MipsELFStreamer.h"
     12 #include "MipsTargetStreamer.h"
     13 #include "llvm/BinaryFormat/ELF.h"
     14 #include "llvm/MC/MCAssembler.h"
     15 #include "llvm/MC/MCContext.h"
     16 #include "llvm/MC/MCRegisterInfo.h"
     17 #include "llvm/MC/MCSectionELF.h"
     18 #include <cassert>
     19 
     20 using namespace llvm;
     21 
     22 void MipsRegInfoRecord::EmitMipsOptionRecord() {
     23   MCAssembler &MCA = Streamer->getAssembler();
     24   MipsTargetStreamer *MTS =
     25       static_cast<MipsTargetStreamer *>(Streamer->getTargetStreamer());
     26 
     27   Streamer->PushSection();
     28 
     29   // We need to distinguish between N64 and the rest because at the moment
     30   // we don't emit .Mips.options for other ELFs other than N64.
     31   // Since .reginfo has the same information as .Mips.options (ODK_REGINFO),
     32   // we can use the same abstraction (MipsRegInfoRecord class) to handle both.
     33   if (MTS->getABI().IsN64()) {
     34     // The EntrySize value of 1 seems strange since the records are neither
     35     // 1-byte long nor fixed length but it matches the value GAS emits.
     36     MCSectionELF *Sec =
     37         Context.getELFSection(".MIPS.options", ELF::SHT_MIPS_OPTIONS,
     38                               ELF::SHF_ALLOC | ELF::SHF_MIPS_NOSTRIP, 1);
     39     MCA.registerSection(*Sec);
     40     Sec->setAlignment(Align(8));
     41     Streamer->SwitchSection(Sec);
     42 
     43     Streamer->emitInt8(ELF::ODK_REGINFO); // kind
     44     Streamer->emitInt8(40);               // size
     45     Streamer->emitInt16(0);               // section
     46     Streamer->emitInt32(0);               // info
     47     Streamer->emitInt32(ri_gprmask);
     48     Streamer->emitInt32(0); // pad
     49     Streamer->emitInt32(ri_cprmask[0]);
     50     Streamer->emitInt32(ri_cprmask[1]);
     51     Streamer->emitInt32(ri_cprmask[2]);
     52     Streamer->emitInt32(ri_cprmask[3]);
     53     Streamer->emitIntValue(ri_gp_value, 8);
     54   } else {
     55     MCSectionELF *Sec = Context.getELFSection(".reginfo", ELF::SHT_MIPS_REGINFO,
     56                                               ELF::SHF_ALLOC, 24);
     57     MCA.registerSection(*Sec);
     58     Sec->setAlignment(MTS->getABI().IsN32() ? Align(8) : Align(4));
     59     Streamer->SwitchSection(Sec);
     60 
     61     Streamer->emitInt32(ri_gprmask);
     62     Streamer->emitInt32(ri_cprmask[0]);
     63     Streamer->emitInt32(ri_cprmask[1]);
     64     Streamer->emitInt32(ri_cprmask[2]);
     65     Streamer->emitInt32(ri_cprmask[3]);
     66     assert((ri_gp_value & 0xffffffff) == ri_gp_value);
     67     Streamer->emitInt32(ri_gp_value);
     68   }
     69 
     70   Streamer->PopSection();
     71 }
     72 
     73 void MipsRegInfoRecord::SetPhysRegUsed(unsigned Reg,
     74                                        const MCRegisterInfo *MCRegInfo) {
     75   unsigned Value = 0;
     76 
     77   for (const MCPhysReg &SubReg : MCRegInfo->subregs_inclusive(Reg)) {
     78     unsigned EncVal = MCRegInfo->getEncodingValue(SubReg);
     79     Value |= 1 << EncVal;
     80 
     81     if (GPR32RegClass->contains(SubReg) || GPR64RegClass->contains(SubReg))
     82       ri_gprmask |= Value;
     83     else if (COP0RegClass->contains(SubReg))
     84       ri_cprmask[0] |= Value;
     85     // MIPS COP1 is the FPU.
     86     else if (FGR32RegClass->contains(SubReg) ||
     87              FGR64RegClass->contains(SubReg) ||
     88              AFGR64RegClass->contains(SubReg) ||
     89              MSA128BRegClass->contains(SubReg))
     90       ri_cprmask[1] |= Value;
     91     else if (COP2RegClass->contains(SubReg))
     92       ri_cprmask[2] |= Value;
     93     else if (COP3RegClass->contains(SubReg))
     94       ri_cprmask[3] |= Value;
     95   }
     96 }
     97