diff options
author | dim <dim@FreeBSD.org> | 2014-03-26 07:31:57 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-03-26 07:31:57 +0000 |
commit | fb422e6d310915f9e2641190198698d922f7ef58 (patch) | |
tree | 8126abc77e6620e23932d186c7b2b75457af47a5 /contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp | |
parent | 5a582ae617991f602ee6f8a954a36fd749aa466c (diff) | |
download | FreeBSD-src-fb422e6d310915f9e2641190198698d922f7ef58.zip FreeBSD-src-fb422e6d310915f9e2641190198698d922f7ef58.tar.gz |
MFC r262613:
Merge the projects/clang-sparc64 branch back to head. This brings in
several updates from the llvm and clang trunks to make the sparc64
backend fully functional.
Apart from one patch to sys/sparc64/include/pcpu.h which is still under
discussion, this makes it possible to let clang fully build world and
kernel for sparc64.
Any assistance with testing this on actual sparc64 hardware is greatly
appreciated, as there will unavoidably be bugs left.
Many thanks go to Roman Divacky for his upstream work on getting the
sparc64 backend into shape.
MFC r262985:
Repair a few minor mismerges from r262261 in the clang-sparc64 project
branch. This is also to minimize differences with upstream.
Diffstat (limited to 'contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp')
-rw-r--r-- | contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp b/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp new file mode 100644 index 0000000..6d7457a --- /dev/null +++ b/contrib/llvm/lib/Target/Sparc/InstPrinter/SparcInstPrinter.cpp @@ -0,0 +1,129 @@ +//===-- SparcInstPrinter.cpp - Convert Sparc MCInst to assembly syntax -----==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class prints an Sparc MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "SparcInstPrinter.h" + +#include "Sparc.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +#define GET_INSTRUCTION_NAME +#define PRINT_ALIAS_INSTR +#include "SparcGenAsmWriter.inc" + +void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const +{ + OS << '%' << StringRef(getRegisterName(RegNo)).lower(); +} + +void SparcInstPrinter::printInst(const MCInst *MI, raw_ostream &O, + StringRef Annot) +{ + if (!printAliasInstr(MI, O) && !printSparcAliasInstr(MI, O)) + printInstruction(MI, O); + printAnnotation(O, Annot); +} + +bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI, raw_ostream &O) +{ + switch (MI->getOpcode()) { + default: return false; + case SP::JMPLrr: + case SP::JMPLri: { + if (MI->getNumOperands() != 3) + return false; + if (!MI->getOperand(0).isReg()) + return false; + switch (MI->getOperand(0).getReg()) { + default: return false; + case SP::G0: // jmp $addr + O << "\tjmp "; printMemOperand(MI, 1, O); + return true; + case SP::O7: // call $addr + O << "\tcall "; printMemOperand(MI, 1, O); + return true; + } + } + } +} + +void SparcInstPrinter::printOperand(const MCInst *MI, int opNum, + raw_ostream &O) +{ + const MCOperand &MO = MI->getOperand (opNum); + + if (MO.isReg()) { + printRegName(O, MO.getReg()); + return ; + } + + if (MO.isImm()) { + O << (int)MO.getImm(); + return; + } + + assert(MO.isExpr() && "Unknown operand kind in printOperand"); + MO.getExpr()->print(O); +} + +void SparcInstPrinter::printMemOperand(const MCInst *MI, int opNum, + raw_ostream &O, const char *Modifier) +{ + printOperand(MI, opNum, O); + + // If this is an ADD operand, emit it like normal operands. + if (Modifier && !strcmp(Modifier, "arith")) { + O << ", "; + printOperand(MI, opNum+1, O); + return; + } + const MCOperand &MO = MI->getOperand(opNum+1); + + if (MO.isReg() && MO.getReg() == SP::G0) + return; // don't print "+%g0" + if (MO.isImm() && MO.getImm() == 0) + return; // don't print "+0" + + O << "+"; + + printOperand(MI, opNum+1, O); +} + +void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum, + raw_ostream &O) +{ + int CC = (int)MI->getOperand(opNum).getImm(); + switch (MI->getOpcode()) { + default: break; + case SP::FBCOND: + case SP::MOVFCCrr: + case SP::MOVFCCri: + case SP::FMOVS_FCC: + case SP::FMOVD_FCC: + case SP::FMOVQ_FCC: // Make sure CC is a fp conditional flag. + CC = (CC < 16) ? (CC + 16) : CC; + break; + } + O << SPARCCondCodeToString((SPCC::CondCodes)CC); +} + +bool SparcInstPrinter::printGetPCX(const MCInst *MI, unsigned opNum, + raw_ostream &O) +{ + assert(0 && "FIXME: Implement SparcInstPrinter::printGetPCX."); + return true; +} |