diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
commit | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch) | |
tree | 599ab169a01f1c86eda9adc774edaedde2f2db5b /lib/Target/ARM/ARMAsmPrinter.cpp | |
parent | 1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff) |
Notes
Diffstat (limited to 'lib/Target/ARM/ARMAsmPrinter.cpp')
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 153 |
1 files changed, 109 insertions, 44 deletions
diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index b7cd3a0c2dae..e29077266fcd 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -1,9 +1,8 @@ //===-- ARMAsmPrinter.cpp - Print machine code to an ARM .s file ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -18,9 +17,10 @@ #include "ARMMachineFunctionInfo.h" #include "ARMTargetMachine.h" #include "ARMTargetObjectFile.h" -#include "InstPrinter/ARMInstPrinter.h" #include "MCTargetDesc/ARMAddressingModes.h" +#include "MCTargetDesc/ARMInstPrinter.h" #include "MCTargetDesc/ARMMCExpr.h" +#include "TargetInfo/ARMTargetInfo.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallString.h" #include "llvm/BinaryFormat/COFF.h" @@ -120,13 +120,13 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { // Calculate this function's optimization goal. unsigned OptimizationGoal; - if (F.hasFnAttribute(Attribute::OptimizeNone)) + if (F.hasOptNone()) // For best debugging illusion, speed and small size sacrificed OptimizationGoal = 6; - else if (F.optForMinSize()) + else if (F.hasMinSize()) // Aggressively for small size, speed and debug illusion sacrificed OptimizationGoal = 4; - else if (F.optForSize()) + else if (F.hasOptSize()) // For small size, but speed and debugging illusion preserved OptimizationGoal = 3; else if (TM.getOptLevel() == CodeGenOpt::Aggressive) @@ -184,10 +184,21 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) { return false; } +void ARMAsmPrinter::PrintSymbolOperand(const MachineOperand &MO, + raw_ostream &O) { + assert(MO.isGlobal() && "caller should check MO.isGlobal"); + unsigned TF = MO.getTargetFlags(); + if (TF & ARMII::MO_LO16) + O << ":lower16:"; + else if (TF & ARMII::MO_HI16) + O << ":upper16:"; + GetARMGVSymbol(MO.getGlobal(), TF)->print(O, MAI); + printOffset(MO.getOffset(), O); +} + void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O) { const MachineOperand &MO = MI->getOperand(OpNum); - unsigned TF = MO.getTargetFlags(); switch (MO.getType()) { default: llvm_unreachable("<unknown operand type>"); @@ -204,27 +215,20 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum, break; } case MachineOperand::MO_Immediate: { - int64_t Imm = MO.getImm(); O << '#'; + unsigned TF = MO.getTargetFlags(); if (TF == ARMII::MO_LO16) O << ":lower16:"; else if (TF == ARMII::MO_HI16) O << ":upper16:"; - O << Imm; + O << MO.getImm(); break; } case MachineOperand::MO_MachineBasicBlock: MO.getMBB()->getSymbol()->print(O, MAI); return; case MachineOperand::MO_GlobalAddress: { - const GlobalValue *GV = MO.getGlobal(); - if (TF & ARMII::MO_LO16) - O << ":lower16:"; - else if (TF & ARMII::MO_HI16) - O << ":upper16:"; - GetARMGVSymbol(GV, TF)->print(O, MAI); - - printOffset(MO.getOffset(), O); + PrintSymbolOperand(MO, O); break; } case MachineOperand::MO_ConstantPoolIndex: @@ -256,8 +260,7 @@ GetARMJTIPICJumpTableLabel(unsigned uid) const { } bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &O) { + const char *ExtraCode, raw_ostream &O) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. @@ -265,20 +268,7 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, switch (ExtraCode[0]) { default: // See if this is a generic print operand - return AsmPrinter::PrintAsmOperand(MI, OpNum, AsmVariant, ExtraCode, O); - case 'a': // Print as a memory address. - if (MI->getOperand(OpNum).isReg()) { - O << "[" - << ARMInstPrinter::getRegisterName(MI->getOperand(OpNum).getReg()) - << "]"; - return false; - } - LLVM_FALLTHROUGH; - case 'c': // Don't print "#" before an immediate operand. - if (!MI->getOperand(OpNum).isImm()) - return true; - O << MI->getOperand(OpNum).getImm(); - return false; + return AsmPrinter::PrintAsmOperand(MI, OpNum, ExtraCode, O); case 'P': // Print a VFP double precision register. case 'q': // Print a NEON quad precision register. printOperand(MI, OpNum, O); @@ -444,8 +434,7 @@ bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum, } bool ARMAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, - unsigned OpNum, unsigned AsmVariant, - const char *ExtraCode, + unsigned OpNum, const char *ExtraCode, raw_ostream &O) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { @@ -668,7 +657,7 @@ void ARMAsmPrinter::emitAttributes() { ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::IEEEDenormals); else { - if (!STI.hasVFP2()) { + if (!STI.hasVFP2Base()) { // When the target doesn't have an FPU (by design or // intention), the assumptions made on the software support // mirror that of the equivalent hardware support *if it @@ -678,7 +667,7 @@ void ARMAsmPrinter::emitAttributes() { if (STI.hasV7Ops()) ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::PreserveFPSign); - } else if (STI.hasVFP3()) { + } else if (STI.hasVFP3Base()) { // In VFPv4, VFPv4U, VFPv3, or VFPv3U, it is preserved. That is, // the sign bit of the zero matches the sign bit of the input or // result that is being flushed to zero. @@ -773,6 +762,14 @@ void ARMAsmPrinter::emitAttributes() { //===----------------------------------------------------------------------===// +static MCSymbol *getBFLabel(StringRef Prefix, unsigned FunctionNumber, + unsigned LabelId, MCContext &Ctx) { + + MCSymbol *Label = Ctx.getOrCreateSymbol(Twine(Prefix) + + "BF" + Twine(FunctionNumber) + "_" + Twine(LabelId)); + return Label; +} + static MCSymbol *getPICLabel(StringRef Prefix, unsigned FunctionNumber, unsigned LabelId, MCContext &Ctx) { @@ -1074,7 +1071,6 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { const TargetRegisterInfo *TargetRegInfo = MF.getSubtarget().getRegisterInfo(); const MachineRegisterInfo &MachineRegInfo = MF.getRegInfo(); - const ARMFunctionInfo &AFI = *MF.getInfo<ARMFunctionInfo>(); unsigned FramePtr = TargetRegInfo->getFrameRegister(MF); unsigned Opc = MI->getOpcode(); @@ -1138,7 +1134,12 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { Pad += Width; continue; } - RegList.push_back(MO.getReg()); + // Check for registers that are remapped (for a Thumb1 prologue that + // saves high registers). + unsigned Reg = MO.getReg(); + if (unsigned RemappedReg = AFI->EHPrologueRemappedRegs.lookup(Reg)) + Reg = RemappedReg; + RegList.push_back(Reg); } break; case ARM::STR_PRE_IMM: @@ -1188,7 +1189,7 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { unsigned CPI = MI->getOperand(1).getIndex(); const MachineConstantPool *MCP = MF.getConstantPool(); if (CPI >= MCP->getConstants().size()) - CPI = AFI.getOriginalCPIdx(CPI); + CPI = AFI->getOriginalCPIdx(CPI); assert(CPI != -1U && "Invalid constpool index"); // Derive the actual offset. @@ -1218,8 +1219,12 @@ void ARMAsmPrinter::EmitUnwindingInstruction(const MachineInstr *MI) { } else if (DstReg == ARM::SP) { MI->print(errs()); llvm_unreachable("Unsupported opcode for unwinding information"); - } - else { + } else if (Opc == ARM::tMOVr) { + // If a Thumb1 function spills r8-r11, we copy the values to low + // registers before pushing them. Record the copy so we can emit the + // correct ".save" later. + AFI->EHPrologueRemappedRegs[DstReg] = SrcReg; + } else { MI->print(errs()); llvm_unreachable("Unsupported opcode for unwinding information"); } @@ -1447,6 +1452,66 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) { EmitToStreamer(*OutStreamer, TmpInst); return; } + case ARM::t2BFi: + case ARM::t2BFic: + case ARM::t2BFLi: + case ARM::t2BFr: + case ARM::t2BFLr: { + // This is a Branch Future instruction. + + const MCExpr *BranchLabel = MCSymbolRefExpr::create( + getBFLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(), + MI->getOperand(0).getIndex(), OutContext), + OutContext); + + auto MCInst = MCInstBuilder(Opc).addExpr(BranchLabel); + if (MI->getOperand(1).isReg()) { + // For BFr/BFLr + MCInst.addReg(MI->getOperand(1).getReg()); + } else { + // For BFi/BFLi/BFic + const MCExpr *BranchTarget; + if (MI->getOperand(1).isMBB()) + BranchTarget = MCSymbolRefExpr::create( + MI->getOperand(1).getMBB()->getSymbol(), OutContext); + else if (MI->getOperand(1).isGlobal()) { + const GlobalValue *GV = MI->getOperand(1).getGlobal(); + BranchTarget = MCSymbolRefExpr::create( + GetARMGVSymbol(GV, MI->getOperand(1).getTargetFlags()), OutContext); + } else if (MI->getOperand(1).isSymbol()) { + BranchTarget = MCSymbolRefExpr::create( + GetExternalSymbolSymbol(MI->getOperand(1).getSymbolName()), + OutContext); + } else + llvm_unreachable("Unhandled operand kind in Branch Future instruction"); + + MCInst.addExpr(BranchTarget); + } + + if (Opc == ARM::t2BFic) { + const MCExpr *ElseLabel = MCSymbolRefExpr::create( + getBFLabel(DL.getPrivateGlobalPrefix(), getFunctionNumber(), + MI->getOperand(2).getIndex(), OutContext), + OutContext); + MCInst.addExpr(ElseLabel); + MCInst.addImm(MI->getOperand(3).getImm()); + } else { + MCInst.addImm(MI->getOperand(2).getImm()) + .addReg(MI->getOperand(3).getReg()); + } + + EmitToStreamer(*OutStreamer, MCInst); + return; + } + case ARM::t2BF_LabelPseudo: { + // This is a pseudo op for a label used by a branch future instruction + + // Emit the label. + OutStreamer->EmitLabel(getBFLabel(DL.getPrivateGlobalPrefix(), + getFunctionNumber(), + MI->getOperand(0).getIndex(), OutContext)); + return; + } case ARM::tPICADD: { // This is a pseudo op for a label + instruction sequence, which looks like: // LPC0: |