From: Wesley Peck Date: Thu, 21 Oct 2010 03:09:55 +0000 (+0000) Subject: Major update of the MicroBlaze backend. The new features are: X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=13a949071ce2c887ae81db9f6880a660ff33a76d;p=oota-llvm.git Major update of the MicroBlaze backend. The new features are: 1. A delay slot filler that searches for valid instructions to fill the delay slot with. Previously NOPs would always be inserted into delay slots. 2. Support for MC based instruction printer added. 3. Support for MC based machine code generation and ELF file generation. ELF file generation does not yet completely work as much of the ELF support infrastructure is still x86/x86-64 specific. 4. General clean up of the MBlaze backend code. Much of the tablegen code has been cleanup and simplified. Bug Fixes: 1. Removed duplicate periods from subtarget feature descriptions. 2. Many of the instructions had bad machine code information in the tablegen files. Much of this has been fixed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116986 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/cmake/modules/LLVMLibDeps.cmake b/cmake/modules/LLVMLibDeps.cmake index 67a016c641a..8c8db9326e0 100644 --- a/cmake/modules/LLVMLibDeps.cmake +++ b/cmake/modules/LLVMLibDeps.cmake @@ -1,28 +1,28 @@ -set(MSVC_LIB_DEPS_LLVMARMAsmParser LLVMARMCodeGen LLVMARMInfo LLVMMC LLVMMCParser LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMARMAsmPrinter LLVMMC LLVMSupport) +set(MSVC_LIB_DEPS_LLVMARMAsmParser LLVMARMInfo LLVMMC LLVMMCParser LLVMSupport LLVMSystem LLVMTarget) +set(MSVC_LIB_DEPS_LLVMARMAsmPrinter LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMARMCodeGen LLVMARMAsmPrinter LLVMARMInfo LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMARMDisassembler LLVMARMCodeGen LLVMARMInfo LLVMMC LLVMSupport) +set(MSVC_LIB_DEPS_LLVMARMDisassembler LLVMARMCodeGen LLVMARMInfo LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMARMInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMAlphaAsmPrinter LLVMAlphaCodeGen LLVMAlphaInfo LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMAlphaAsmPrinter LLVMAlphaInfo LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMAlphaCodeGen LLVMAlphaInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMAlphaInfo LLVMSupport) set(MSVC_LIB_DEPS_LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMSystem) -set(MSVC_LIB_DEPS_LLVMAsmParser LLVMCore LLVMSupport) +set(MSVC_LIB_DEPS_LLVMAsmParser LLVMCore LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMAsmPrinter LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMMCParser LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMBitReader LLVMCore LLVMSupport) -set(MSVC_LIB_DEPS_LLVMBitWriter LLVMCore LLVMSupport) -set(MSVC_LIB_DEPS_LLVMBlackfinAsmPrinter LLVMAsmPrinter LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMBitReader LLVMCore LLVMSupport LLVMSystem) +set(MSVC_LIB_DEPS_LLVMBitWriter LLVMCore LLVMSupport LLVMSystem) +set(MSVC_LIB_DEPS_LLVMBlackfinAsmPrinter LLVMAsmPrinter LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget) +set(MSVC_LIB_DEPS_LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMBlackfinInfo LLVMSupport) set(MSVC_LIB_DEPS_LLVMCBackend LLVMAnalysis LLVMCBackendInfo LLVMCodeGen LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils LLVMipa) set(MSVC_LIB_DEPS_LLVMCBackendInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMCellSPUAsmPrinter LLVMAsmPrinter LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMCellSPUAsmPrinter LLVMAsmPrinter LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget) +set(MSVC_LIB_DEPS_LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMCellSPUInfo LLVMSupport) set(MSVC_LIB_DEPS_LLVMCodeGen LLVMAnalysis LLVMCore LLVMMC LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils) set(MSVC_LIB_DEPS_LLVMCore LLVMSupport LLVMSystem) -set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMCppBackend LLVMCore LLVMCppBackendInfo LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMCppBackendInfo LLVMSupport) set(MSVC_LIB_DEPS_LLVMExecutionEngine LLVMCore LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMInstCombine LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils) @@ -30,43 +30,43 @@ set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMAnalysis LLVMCore LLVMSupport LLVMSyst set(MSVC_LIB_DEPS_LLVMInterpreter LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMJIT LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMMC LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMLinker LLVMArchive LLVMBitReader LLVMCore LLVMSupport LLVMSystem LLVMTransformUtils) -set(MSVC_LIB_DEPS_LLVMMBlazeAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMSupport LLVMTarget) -set(MSVC_LIB_DEPS_LLVMMBlazeCodeGen LLVMCodeGen LLVMCore LLVMMBlazeInfo LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) +set(MSVC_LIB_DEPS_LLVMMBlazeAsmPrinter LLVMMC LLVMSupport LLVMSystem) +set(MSVC_LIB_DEPS_LLVMMBlazeCodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMBlazeAsmPrinter LLVMMBlazeInfo LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMMBlazeInfo LLVMSupport) set(MSVC_LIB_DEPS_LLVMMC LLVMSupport LLVMSystem) -set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDisassembler LLVMARMInfo LLVMAlphaAsmPrinter LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinAsmPrinter LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUAsmPrinter LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeAsmPrinter LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Info LLVMMipsAsmPrinter LLVMMipsCodeGen LLVMMipsInfo LLVMPTXAsmPrinter LLVMPTXCodeGen LLVMPTXInfo LLVMPowerPCAsmPrinter LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcAsmPrinter LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMSystem LLVMSystemZAsmPrinter LLVMSystemZCodeGen LLVMSystemZInfo LLVMX86AsmParser LLVMX86CodeGen LLVMX86Disassembler LLVMX86Info LLVMXCoreAsmPrinter LLVMXCoreCodeGen LLVMXCoreInfo) -set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport) +set(MSVC_LIB_DEPS_LLVMMCDisassembler LLVMARMAsmParser LLVMARMCodeGen LLVMARMDisassembler LLVMARMInfo LLVMAlphaAsmPrinter LLVMAlphaCodeGen LLVMAlphaInfo LLVMBlackfinAsmPrinter LLVMBlackfinCodeGen LLVMBlackfinInfo LLVMCBackend LLVMCBackendInfo LLVMCellSPUAsmPrinter LLVMCellSPUCodeGen LLVMCellSPUInfo LLVMCppBackend LLVMCppBackendInfo LLVMMBlazeCodeGen LLVMMBlazeInfo LLVMMC LLVMMCParser LLVMMSP430CodeGen LLVMMSP430Info LLVMMipsAsmPrinter LLVMMipsCodeGen LLVMMipsInfo LLVMPTXAsmPrinter LLVMPTXCodeGen LLVMPTXInfo LLVMPowerPCAsmPrinter LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSparcAsmPrinter LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMSystem LLVMSystemZAsmPrinter LLVMSystemZCodeGen LLVMSystemZInfo LLVMX86AsmParser LLVMX86CodeGen LLVMX86Disassembler LLVMX86Info LLVMXCoreAsmPrinter LLVMXCoreCodeGen LLVMXCoreInfo) +set(MSVC_LIB_DEPS_LLVMMCParser LLVMMC LLVMSupport LLVMSystem) +set(MSVC_LIB_DEPS_LLVMMSP430AsmPrinter LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMMSP430CodeGen LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMSP430AsmPrinter LLVMMSP430Info LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMMSP430Info LLVMSupport) -set(MSVC_LIB_DEPS_LLVMMipsAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMipsCodeGen LLVMMipsInfo LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMMipsAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMMipsCodeGen LLVMMipsInfo LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMMipsCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMMipsInfo LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMMipsInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMPTXAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMPTXCodeGen LLVMPTXInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMPTXCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMPTXInfo LLVMSelectionDAG LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMPTXAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMPTXInfo LLVMSupport LLVMSystem) +set(MSVC_LIB_DEPS_LLVMPTXCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMPTXInfo LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMPTXInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMPowerPCAsmPrinter LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCCodeGen LLVMPowerPCInfo LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMPowerPCAsmPrinter LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCInfo LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMPowerPCCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMPowerPCInfo LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMPowerPCInfo LLVMSupport) set(MSVC_LIB_DEPS_LLVMScalarOpts LLVMAnalysis LLVMCore LLVMInstCombine LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils) set(MSVC_LIB_DEPS_LLVMSelectionDAG LLVMAnalysis LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget) -set(MSVC_LIB_DEPS_LLVMSparcAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSparcCodeGen LLVMSparcInfo LLVMSupport LLVMTarget) +set(MSVC_LIB_DEPS_LLVMSparcAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSparcInfo LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMSparcCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSparcInfo LLVMSupport LLVMSystem LLVMTarget) set(MSVC_LIB_DEPS_LLVMSparcInfo LLVMSupport) set(MSVC_LIB_DEPS_LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMSystem ) -set(MSVC_LIB_DEPS_LLVMSystemZAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystemZCodeGen LLVMSystemZInfo LLVMTarget) -set(MSVC_LIB_DEPS_LLVMSystemZCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystemZInfo LLVMTarget) +set(MSVC_LIB_DEPS_LLVMSystemZAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMSystemZInfo LLVMTarget) +set(MSVC_LIB_DEPS_LLVMSystemZCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMSystemZInfo LLVMTarget) set(MSVC_LIB_DEPS_LLVMSystemZInfo LLVMSupport) -set(MSVC_LIB_DEPS_LLVMTarget LLVMCore LLVMMC LLVMSupport) +set(MSVC_LIB_DEPS_LLVMTarget LLVMCore LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMTransformUtils LLVMAnalysis LLVMCore LLVMSupport LLVMSystem LLVMTarget LLVMipa) -set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMMCParser LLVMSupport LLVMTarget LLVMX86Info) -set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMMC LLVMSupport) +set(MSVC_LIB_DEPS_LLVMX86AsmParser LLVMMC LLVMMCParser LLVMSupport LLVMSystem LLVMTarget LLVMX86Info) +set(MSVC_LIB_DEPS_LLVMX86AsmPrinter LLVMMC LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMX86CodeGen LLVMAnalysis LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMX86AsmPrinter LLVMX86Info) set(MSVC_LIB_DEPS_LLVMX86Disassembler LLVMMC LLVMSupport LLVMX86Info) set(MSVC_LIB_DEPS_LLVMX86Info LLVMSupport) -set(MSVC_LIB_DEPS_LLVMXCoreAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMTarget LLVMXCoreCodeGen LLVMXCoreInfo) -set(MSVC_LIB_DEPS_LLVMXCoreCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMTarget LLVMXCoreInfo) +set(MSVC_LIB_DEPS_LLVMXCoreAsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMMC LLVMSupport LLVMSystem LLVMTarget LLVMXCoreInfo) +set(MSVC_LIB_DEPS_LLVMXCoreCodeGen LLVMCodeGen LLVMCore LLVMMC LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget LLVMXCoreInfo) set(MSVC_LIB_DEPS_LLVMXCoreInfo LLVMSupport) set(MSVC_LIB_DEPS_LLVMipa LLVMAnalysis LLVMCore LLVMSupport LLVMSystem) set(MSVC_LIB_DEPS_LLVMipo LLVMAnalysis LLVMCore LLVMScalarOpts LLVMSupport LLVMSystem LLVMTarget LLVMTransformUtils LLVMipa) diff --git a/lib/Target/MBlaze/AsmPrinter/CMakeLists.txt b/lib/Target/MBlaze/AsmPrinter/CMakeLists.txt deleted file mode 100644 index fac2c1959d7..00000000000 --- a/lib/Target/MBlaze/AsmPrinter/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -include_directories( - ${CMAKE_CURRENT_BINARY_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ) - -add_llvm_library(LLVMMBlazeAsmPrinter - MBlazeAsmPrinter.cpp - ) -add_dependencies(LLVMMBlazeAsmPrinter MBlazeCodeGenTable_gen) diff --git a/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp deleted file mode 100644 index f4b30ad271f..00000000000 --- a/lib/Target/MBlaze/AsmPrinter/MBlazeAsmPrinter.cpp +++ /dev/null @@ -1,295 +0,0 @@ -//===-- MBlazeAsmPrinter.cpp - MBlaze LLVM assembly writer ----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains a printer that converts from our internal representation -// of machine-dependent LLVM code to GAS-format MBlaze assembly language. -// -//===----------------------------------------------------------------------===// - -#define DEBUG_TYPE "mblaze-asm-printer" - -#include "MBlaze.h" -#include "MBlazeSubtarget.h" -#include "MBlazeInstrInfo.h" -#include "MBlazeTargetMachine.h" -#include "MBlazeMachineFunction.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Module.h" -#include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineConstantPool.h" -#include "llvm/CodeGen/MachineFrameInfo.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegistry.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include - -using namespace llvm; - -namespace { - class MBlazeAsmPrinter : public AsmPrinter { - const MBlazeSubtarget *Subtarget; - public: - explicit MBlazeAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) - : AsmPrinter(TM, Streamer) { - Subtarget = &TM.getSubtarget(); - } - - virtual const char *getPassName() const { - return "MBlaze Assembly Printer"; - } - - bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, const char *ExtraCode, - raw_ostream &O); - void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); - void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O); - void printFSLImm(const MachineInstr *MI, int opNum, raw_ostream &O); - void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, - const char *Modifier = 0); - void printSavedRegsBitmask(raw_ostream &OS); - - void emitFrameDirective(); - - void printInstruction(const MachineInstr *MI, raw_ostream &O); - void EmitInstruction(const MachineInstr *MI) { - SmallString<128> Str; - raw_svector_ostream OS(Str); - printInstruction(MI, OS); - OutStreamer.EmitRawText(OS.str()); - } - virtual void EmitFunctionBodyStart(); - virtual void EmitFunctionBodyEnd(); - static const char *getRegisterName(unsigned RegNo); - - virtual void EmitFunctionEntryLabel(); - }; -} // end of anonymous namespace - -#include "MBlazeGenAsmWriter.inc" - -//===----------------------------------------------------------------------===// -// -// MBlaze Asm Directives -// -// -- Frame directive "frame Stackpointer, Stacksize, RARegister" -// Describe the stack frame. -// -// -- Mask directives "mask bitmask, offset" -// Tells the assembler which registers are saved and where. -// bitmask - contain a little endian bitset indicating which registers are -// saved on function prologue (e.g. with a 0x80000000 mask, the -// assembler knows the register 31 (RA) is saved at prologue. -// offset - the position before stack pointer subtraction indicating where -// the first saved register on prologue is located. (e.g. with a -// -// Consider the following function prologue: -// -// .frame R19,48,R15 -// .mask 0xc0000000,-8 -// addiu R1, R1, -48 -// sw R15, 40(R1) -// sw R19, 36(R1) -// -// With a 0xc0000000 mask, the assembler knows the register 15 (R15) and -// 19 (R19) are saved at prologue. As the save order on prologue is from -// left to right, R15 is saved first. A -8 offset means that after the -// stack pointer subtration, the first register in the mask (R15) will be -// saved at address 48-8=40. -// -//===----------------------------------------------------------------------===// - -//===----------------------------------------------------------------------===// -// Mask directives -//===----------------------------------------------------------------------===// - -// Print a 32 bit hex number with all numbers. -static void printHex32(unsigned int Value, raw_ostream &O) { - O << "0x"; - for (int i = 7; i >= 0; i--) - O << utohexstr((Value & (0xF << (i*4))) >> (i*4)); -} - - -// Create a bitmask with all callee saved registers for CPU or Floating Point -// registers. For CPU registers consider RA, GP and FP for saving if necessary. -void MBlazeAsmPrinter::printSavedRegsBitmask(raw_ostream &O) { - const TargetRegisterInfo &RI = *TM.getRegisterInfo(); - const MBlazeFunctionInfo *MBlazeFI = MF->getInfo(); - - // CPU Saved Registers Bitmasks - unsigned int CPUBitmask = 0; - - // Set the CPU Bitmasks - const MachineFrameInfo *MFI = MF->getFrameInfo(); - const std::vector &CSI = MFI->getCalleeSavedInfo(); - for (unsigned i = 0, e = CSI.size(); i != e; ++i) { - unsigned Reg = CSI[i].getReg(); - unsigned RegNum = MBlazeRegisterInfo::getRegisterNumbering(Reg); - if (MBlaze::CPURegsRegisterClass->contains(Reg)) - CPUBitmask |= (1 << RegNum); - } - - // Return Address and Frame registers must also be set in CPUBitmask. - if (RI.hasFP(*MF)) - CPUBitmask |= (1 << MBlazeRegisterInfo:: - getRegisterNumbering(RI.getFrameRegister(*MF))); - - if (MFI->adjustsStack()) - CPUBitmask |= (1 << MBlazeRegisterInfo:: - getRegisterNumbering(RI.getRARegister())); - - // Print CPUBitmask - O << "\t.mask \t"; printHex32(CPUBitmask, O); - O << ',' << MBlazeFI->getCPUTopSavedRegOff() << '\n'; -} - -//===----------------------------------------------------------------------===// -// Frame and Set directives -//===----------------------------------------------------------------------===// - -/// Frame Directive -void MBlazeAsmPrinter::emitFrameDirective() { - const TargetRegisterInfo &RI = *TM.getRegisterInfo(); - - unsigned stackReg = RI.getFrameRegister(*MF); - unsigned returnReg = RI.getRARegister(); - unsigned stackSize = MF->getFrameInfo()->getStackSize(); - - - OutStreamer.EmitRawText("\t.frame\t" + Twine(getRegisterName(stackReg)) + - "," + Twine(stackSize) + "," + - Twine(getRegisterName(returnReg))); -} - -void MBlazeAsmPrinter::EmitFunctionEntryLabel() { - OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName())); - OutStreamer.EmitLabel(CurrentFnSym); -} - -/// EmitFunctionBodyStart - Targets can override this to emit stuff before -/// the first basic block in the function. -void MBlazeAsmPrinter::EmitFunctionBodyStart() { - emitFrameDirective(); - - SmallString<128> Str; - raw_svector_ostream OS(Str); - printSavedRegsBitmask(OS); - OutStreamer.EmitRawText(OS.str()); -} - -/// EmitFunctionBodyEnd - Targets can override this to emit stuff after -/// the last basic block in the function. -void MBlazeAsmPrinter::EmitFunctionBodyEnd() { - OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName())); -} - -// Print out an operand for an inline asm expression. -bool MBlazeAsmPrinter:: -PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant,const char *ExtraCode, raw_ostream &O) { - // Does this asm operand have a single letter operand modifier? - if (ExtraCode && ExtraCode[0]) - return true; // Unknown modifier. - - printOperand(MI, OpNo, O); - return false; -} - -void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum, - raw_ostream &O) { - const MachineOperand &MO = MI->getOperand(opNum); - - switch (MO.getType()) { - case MachineOperand::MO_Register: - O << getRegisterName(MO.getReg()); - break; - - case MachineOperand::MO_Immediate: - O << (int)MO.getImm(); - break; - - case MachineOperand::MO_FPImmediate: { - const ConstantFP *fp = MO.getFPImm(); - printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue(), O); - O << ";\t# immediate = " << *fp; - break; - } - - case MachineOperand::MO_MachineBasicBlock: - O << *MO.getMBB()->getSymbol(); - return; - - case MachineOperand::MO_GlobalAddress: - O << *Mang->getSymbol(MO.getGlobal()); - break; - - case MachineOperand::MO_ExternalSymbol: - O << *GetExternalSymbolSymbol(MO.getSymbolName()); - break; - - case MachineOperand::MO_JumpTableIndex: - O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << MO.getIndex(); - break; - - case MachineOperand::MO_ConstantPoolIndex: - O << MAI->getPrivateGlobalPrefix() << "CPI" - << getFunctionNumber() << "_" << MO.getIndex(); - if (MO.getOffset()) - O << "+" << MO.getOffset(); - break; - - default: - llvm_unreachable(""); - } -} - -void MBlazeAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum, - raw_ostream &O) { - const MachineOperand &MO = MI->getOperand(opNum); - if (MO.isImm()) - O << (unsigned int)MO.getImm(); - else - printOperand(MI, opNum, O); -} - -void MBlazeAsmPrinter::printFSLImm(const MachineInstr *MI, int opNum, - raw_ostream &O) { - const MachineOperand &MO = MI->getOperand(opNum); - if (MO.isImm()) - O << "rfsl" << (unsigned int)MO.getImm(); - else - printOperand(MI, opNum, O); -} - -void MBlazeAsmPrinter:: -printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, - const char *Modifier) { - printOperand(MI, opNum+1, O); - O << ", "; - printOperand(MI, opNum, O); -} - -// Force static initialization. -extern "C" void LLVMInitializeMBlazeAsmPrinter() { - RegisterAsmPrinter X(TheMBlazeTarget); -} diff --git a/lib/Target/MBlaze/AsmPrinter/Makefile b/lib/Target/MBlaze/AsmPrinter/Makefile deleted file mode 100644 index c44651cc93b..00000000000 --- a/lib/Target/MBlaze/AsmPrinter/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- lib/Target/MBlaze/AsmPrinter/Makefile ---------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../../../.. -LIBRARYNAME = LLVMMBlazeAsmPrinter - -# Hack: we need to include 'main' MBlaze target directory to grab -# private headers -CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. - -include $(LEVEL)/Makefile.common diff --git a/lib/Target/MBlaze/CMakeLists.txt b/lib/Target/MBlaze/CMakeLists.txt index 7b470eec2bd..eb5906e1e70 100644 --- a/lib/Target/MBlaze/CMakeLists.txt +++ b/lib/Target/MBlaze/CMakeLists.txt @@ -5,6 +5,7 @@ tablegen(MBlazeGenRegisterNames.inc -gen-register-enums) tablegen(MBlazeGenRegisterInfo.inc -gen-register-desc) tablegen(MBlazeGenInstrNames.inc -gen-instr-enums) tablegen(MBlazeGenInstrInfo.inc -gen-instr-desc) +tablegen(MBlazeGenCodeEmitter.inc -gen-emitter) tablegen(MBlazeGenAsmWriter.inc -gen-asm-writer) tablegen(MBlazeGenDAGISel.inc -gen-dag-isel) tablegen(MBlazeGenCallingConv.inc -gen-callingconv) @@ -23,4 +24,9 @@ add_llvm_target(MBlazeCodeGen MBlazeTargetObjectFile.cpp MBlazeIntrinsicInfo.cpp MBlazeSelectionDAGInfo.cpp + MBlazeAsmPrinter.cpp + MBlazeAsmBackend.cpp + MBlazeMCInstLower.cpp + MBlazeELFWriterInfo.cpp + MBlazeMCCodeEmitter.cpp ) diff --git a/lib/Target/MBlaze/InstPrinter/CMakeLists.txt b/lib/Target/MBlaze/InstPrinter/CMakeLists.txt new file mode 100644 index 00000000000..242a573036e --- /dev/null +++ b/lib/Target/MBlaze/InstPrinter/CMakeLists.txt @@ -0,0 +1,8 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_llvm_library(LLVMMBlazeAsmPrinter + MBlazeInstPrinter.cpp + ) + +add_dependencies(LLVMMBlazeAsmPrinter MBlazeCodeGenTable_gen) diff --git a/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp b/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp new file mode 100644 index 00000000000..4c59b549ee1 --- /dev/null +++ b/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp @@ -0,0 +1,140 @@ +//===-- MBlazeInstPrinter.cpp - Convert MBlaze 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 MBlaze MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "asm-printer" +#include "MBlaze.h" +#include "MBlazeInstPrinter.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormattedStream.h" +using namespace llvm; + + +// Include the auto-generated portion of the assembly writer. +#include "MBlazeGenAsmWriter.inc" + +void MBlazeInstPrinter::printInst(const MCInst *MI, raw_ostream &O) { + printInstruction(MI, O); +} + +void MBlazeInstPrinter::printPCRelImmOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isImm()) + O << Op.getImm(); + else { + assert(Op.isExpr() && "unknown pcrel immediate operand"); + O << *Op.getExpr(); + } +} + +void MBlazeInstPrinter::printOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O, const char *Modifier) { + assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported"); + const MCOperand &Op = MI->getOperand(OpNo); + if (Op.isReg()) { + O << getRegisterName(Op.getReg()); + } else if (Op.isImm()) { + O << (int32_t)Op.getImm(); + } else { + assert(Op.isExpr() && "unknown operand kind in printOperand"); + O << *Op.getExpr(); + } +} + +void MBlazeInstPrinter::printSrcMemOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O, + const char *Modifier) { + const MCOperand &Base = MI->getOperand(OpNo); + const MCOperand &Disp = MI->getOperand(OpNo+1); + + // Print displacement first + + // If the global address expression is a part of displacement field with a + // register base, we should not emit any prefix symbol here, e.g. + // mov.w &foo, r1 + // vs + // mov.w glb(r1), r2 + // Otherwise (!) msp430-as will silently miscompile the output :( + if (!Base.getReg()) + O << '&'; + + if (Disp.isExpr()) + O << *Disp.getExpr(); + else { + assert(Disp.isImm() && "Expected immediate in displacement field"); + O << Disp.getImm(); + } + + // Print register base field + if (Base.getReg()) + O << getRegisterName(Base.getReg()); +} + +void MBlazeInstPrinter::printFSLImm(const MCInst *MI, int OpNo, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNo); + if (MO.isImm()) + O << "rfsl" << MO.getImm(); + else + printOperand(MI, OpNo, O, NULL); +} + +void MBlazeInstPrinter::printUnsignedImm(const MCInst *MI, int OpNo, + raw_ostream &O) { + const MCOperand &MO = MI->getOperand(OpNo); + if (MO.isImm()) + O << MO.getImm(); + else + printOperand(MI, OpNo, O, NULL); +} + +void MBlazeInstPrinter::printMemOperand(const MCInst *MI, int OpNo, + raw_ostream &O, const char *Modifier ) { + printOperand(MI, OpNo+1, O, NULL); + O << ", "; + printOperand(MI, OpNo, O, NULL); +} + +/* +void MBlazeInstPrinter::printCCOperand(const MCInst *MI, unsigned OpNo, + raw_ostream &O) { + unsigned CC = MI->getOperand(OpNo).getImm(); + + switch (CC) { + default: + llvm_unreachable("Unsupported CC code"); + break; + case MBlazeCC::COND_E: + O << "eq"; + break; + case MBlazeCC::COND_NE: + O << "ne"; + break; + case MBlazeCC::COND_HS: + O << "hs"; + break; + case MBlazeCC::COND_LO: + O << "lo"; + break; + case MBlazeCC::COND_GE: + O << "ge"; + break; + case MBlazeCC::COND_L: + O << 'l'; + break; + } +} +*/ diff --git a/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h b/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h new file mode 100644 index 00000000000..2b80689eaf6 --- /dev/null +++ b/lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h @@ -0,0 +1,46 @@ +//===-- MBLazeInstPrinter.h - Convert MBlaze 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 a MBlaze MCInst to a .s file. +// +//===----------------------------------------------------------------------===// + +#ifndef MBLAZEINSTPRINTER_H +#define MBLAZEINSTPRINTER_H + +#include "llvm/MC/MCInstPrinter.h" + +namespace llvm { + class MCOperand; + + class MBlazeInstPrinter : public MCInstPrinter { + public: + MBlazeInstPrinter(const MCAsmInfo &MAI) : MCInstPrinter(MAI) { + } + + virtual void printInst(const MCInst *MI, raw_ostream &O); + + // Autogenerated by tblgen. + void printInstruction(const MCInst *MI, raw_ostream &O); + static const char *getRegisterName(unsigned RegNo); + static const char *getInstructionName(unsigned Opcode); + + void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, + const char *Modifier = 0); + void printPCRelImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); + void printSrcMemOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, + const char *Modifier = 0); + void printFSLImm(const MCInst *MI, int OpNo, raw_ostream &O); + void printUnsignedImm(const MCInst *MI, int OpNo, raw_ostream &O); + void printMemOperand(const MCInst *MI, int OpNo,raw_ostream &O, + const char *Modifier = 0); + }; +} + +#endif diff --git a/lib/Target/MBlaze/InstPrinter/Makefile b/lib/Target/MBlaze/InstPrinter/Makefile new file mode 100644 index 00000000000..9fb6e869d94 --- /dev/null +++ b/lib/Target/MBlaze/InstPrinter/Makefile @@ -0,0 +1,16 @@ +##===- lib/Target/MBlaze/AsmPrinter/Makefile ---------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. +LIBRARYNAME = LLVMMBlazeAsmPrinter + +# Hack: we need to include 'main' MBlaze target directory to grab +# private headers +CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common diff --git a/lib/Target/MBlaze/MBlaze.h b/lib/Target/MBlaze/MBlaze.h index f9d828b2661..00c73f06fe1 100644 --- a/lib/Target/MBlaze/MBlaze.h +++ b/lib/Target/MBlaze/MBlaze.h @@ -21,8 +21,16 @@ namespace llvm { class MBlazeTargetMachine; class FunctionPass; class MachineCodeEmitter; + class MCCodeEmitter; + class TargetAsmBackend; class formatted_raw_ostream; + MCCodeEmitter *createMBlazeMCCodeEmitter(const Target &, + TargetMachine &TM, + MCContext &Ctx); + + TargetAsmBackend *createMBlazeAsmBackend(const Target &, const std::string &); + FunctionPass *createMBlazeISelDag(MBlazeTargetMachine &TM); FunctionPass *createMBlazeDelaySlotFillerPass(MBlazeTargetMachine &TM); diff --git a/lib/Target/MBlaze/MBlaze.td b/lib/Target/MBlaze/MBlaze.td index 3815b6d0a39..1fa1e4dd577 100644 --- a/lib/Target/MBlaze/MBlaze.td +++ b/lib/Target/MBlaze/MBlaze.td @@ -32,35 +32,35 @@ def MBlazeInstrInfo : InstrInfo; //===----------------------------------------------------------------------===// def FeaturePipe3 : SubtargetFeature<"pipe3", "HasPipe3", "true", - "Implements 3-stage pipeline.">; + "Implements 3-stage pipeline">; def FeatureBarrel : SubtargetFeature<"barrel", "HasBarrel", "true", - "Implements barrel shifter.">; + "Implements barrel shifter">; def FeatureDiv : SubtargetFeature<"div", "HasDiv", "true", - "Implements hardware divider.">; + "Implements hardware divider">; def FeatureMul : SubtargetFeature<"mul", "HasMul", "true", - "Implements hardware multiplier.">; + "Implements hardware multiplier">; def FeatureFSL : SubtargetFeature<"fsl", "HasFSL", "true", - "Implements FSL instructions.">; + "Implements FSL instructions">; def FeatureEFSL : SubtargetFeature<"efsl", "HasEFSL", "true", - "Implements extended FSL instructions.">; + "Implements extended FSL instructions">; def FeatureMSRSet : SubtargetFeature<"msrset", "HasMSRSet", "true", - "Implements MSR register set and clear.">; + "Implements MSR register set and clear">; def FeatureException : SubtargetFeature<"exception", "HasException", "true", - "Implements hardware exception support.">; + "Implements hardware exception support">; def FeaturePatCmp : SubtargetFeature<"patcmp", "HasPatCmp", "true", - "Implements pattern compare instruction.">; + "Implements pattern compare instruction">; def FeatureFPU : SubtargetFeature<"fpu", "HasFPU", "true", - "Implements floating point unit.">; + "Implements floating point unit">; def FeatureESR : SubtargetFeature<"esr", "HasESR", "true", "Implements ESR and EAR registers">; def FeaturePVR : SubtargetFeature<"pvr", "HasPVR", "true", - "Implements processor version register.">; + "Implements processor version register">; def FeatureMul64 : SubtargetFeature<"mul64", "HasMul64", "true", "Implements multiplier with 64-bit result">; def FeatureSqrt : SubtargetFeature<"sqrt", "HasSqrt", "true", - "Implements sqrt and floating point convert.">; + "Implements sqrt and floating point convert">; def FeatureMMU : SubtargetFeature<"mmu", "HasMMU", "true", - "Implements memory management unit.">; + "Implements memory management unit">; //===----------------------------------------------------------------------===// // MBlaze processors supported. @@ -69,13 +69,26 @@ def FeatureMMU : SubtargetFeature<"mmu", "HasMMU", "true", class Proc Features> : Processor; - def : Proc<"v400", []>; def : Proc<"v500", []>; def : Proc<"v600", []>; def : Proc<"v700", []>; def : Proc<"v710", []>; +//===----------------------------------------------------------------------===// +// Instruction Descriptions +//===----------------------------------------------------------------------===// + +def MBlazeAsmWriter : AsmWriter { + string AsmWriterClassName = "InstPrinter"; + bit isMCAsmWriter = 1; +} + +//===----------------------------------------------------------------------===// +// Target Declaration +//===----------------------------------------------------------------------===// + def MBlaze : Target { let InstructionSet = MBlazeInstrInfo; + let AssemblyWriters = [MBlazeAsmWriter]; } diff --git a/lib/Target/MBlaze/MBlazeAsmBackend.cpp b/lib/Target/MBlaze/MBlazeAsmBackend.cpp new file mode 100644 index 00000000000..7e11f7371e5 --- /dev/null +++ b/lib/Target/MBlaze/MBlazeAsmBackend.cpp @@ -0,0 +1,152 @@ +//===-- MBlazeAsmBackend.cpp - MBlaze Assembler Backend -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Target/TargetAsmBackend.h" +#include "MBlaze.h" +#include "MBlazeFixupKinds.h" +#include "llvm/ADT/Twine.h" +#include "llvm/MC/ELFObjectWriter.h" +#include "llvm/MC/MCAssembler.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCObjectFormat.h" +#include "llvm/MC/MCObjectWriter.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCSectionMachO.h" +#include "llvm/MC/MachObjectWriter.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/Target/TargetAsmBackend.h" +using namespace llvm; + +static unsigned getFixupKindSize(unsigned Kind) { + switch (Kind) { + default: assert(0 && "invalid fixup kind!"); + case FK_Data_1: return 1; + case MBlaze::reloc_pcrel_2byte: + case FK_Data_2: return 2; + case MBlaze::reloc_pcrel_4byte: + case FK_Data_4: return 4; + case FK_Data_8: return 8; + } +} + + +namespace { +class MBlazeAsmBackend : public TargetAsmBackend { +public: + MBlazeAsmBackend(const Target &T) + : TargetAsmBackend(T) { + } + + bool MayNeedRelaxation(const MCInst &Inst) const; + + void RelaxInstruction(const MCInst &Inst, MCInst &Res) const; + + bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const; + + unsigned getPointerSize() const { + return 4; + } +}; + +bool MBlazeAsmBackend::MayNeedRelaxation(const MCInst &Inst) const { + return false; +} + +void MBlazeAsmBackend::RelaxInstruction(const MCInst &Inst, MCInst &Res) const { + assert(0 && "MBlazeAsmBackend::RelaxInstruction() unimplemented"); + return; +} + +bool MBlazeAsmBackend::WriteNopData(uint64_t Count, MCObjectWriter *OW) const { + if ((Count % 4) != 0) + return false; + + for (uint64_t i = 0; i < Count; i += 4 ) + OW->Write32( 0x00000000 ); + + return true; +} +} // end anonymous namespace + +namespace { +// FIXME: This should be in a separate file. +// ELF is an ELF of course... +class ELFMBlazeAsmBackend : public MBlazeAsmBackend { + MCELFObjectFormat Format; + +public: + Triple::OSType OSType; + ELFMBlazeAsmBackend(const Target &T, Triple::OSType _OSType) + : MBlazeAsmBackend(T), OSType(_OSType) { + HasScatteredSymbols = true; + } + + virtual const MCObjectFormat &getObjectFormat() const { + return Format; + } + + + void ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF, + uint64_t Value) const; + + bool isVirtualSection(const MCSection &Section) const { + const MCSectionELF &SE = static_cast(Section); + return SE.getType() == MCSectionELF::SHT_NOBITS; + } + + MCObjectWriter *createObjectWriter(raw_ostream &OS) const { + return new ELFObjectWriter(OS, /*Is64Bit=*/false, + OSType, + /*IsLittleEndian=*/false, + /*HasRelocationAddend=*/true); + } +}; + +void ELFMBlazeAsmBackend::ApplyFixup(const MCFixup &Fixup, MCDataFragment &DF, + uint64_t Value) const { + unsigned Size = getFixupKindSize(Fixup.getKind()); + + assert(Fixup.getOffset() + Size <= DF.getContents().size() && + "Invalid fixup offset!"); + + char *data = DF.getContents().data() + Fixup.getOffset(); + switch (Size) { + default: llvm_unreachable( "Cannot fixup unknown value." ); + case 1: llvm_unreachable( "Cannot fixup 1 byte value." ); + case 8: llvm_unreachable( "Cannot fixup 8 byte value." ); + + case 4: + *(data+7) = uint8_t(Value); + *(data+6) = uint8_t(Value >> 8); + *(data+3) = uint8_t(Value >> 16); + *(data+2) = uint8_t(Value >> 24); + break; + + case 2: + *(data+3) = uint8_t(Value >> 0); + *(data+2) = uint8_t(Value >> 8); + } +} +} // end anonymous namespace + +TargetAsmBackend *llvm::createMBlazeAsmBackend(const Target &T, + const std::string &TT) { + switch (Triple(TT).getOS()) { + case Triple::Darwin: + assert(0 && "Mac not supported on MBlaze"); + case Triple::MinGW32: + case Triple::Cygwin: + case Triple::Win32: + assert(0 && "Windows not supported on MBlaze"); + default: + return new ELFMBlazeAsmBackend(T, Triple(TT).getOS()); + } +} diff --git a/lib/Target/MBlaze/MBlazeAsmPrinter.cpp b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp new file mode 100644 index 00000000000..c1ae4502ad5 --- /dev/null +++ b/lib/Target/MBlaze/MBlazeAsmPrinter.cpp @@ -0,0 +1,314 @@ +//===-- MBlazeAsmPrinter.cpp - MBlaze LLVM assembly writer ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a printer that converts from our internal representation +// of machine-dependent LLVM code to GAS-format MBlaze assembly language. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "mblaze-asm-printer" + +#include "MBlaze.h" +#include "MBlazeSubtarget.h" +#include "MBlazeInstrInfo.h" +#include "MBlazeTargetMachine.h" +#include "MBlazeMachineFunction.h" +#include "MBlazeMCInstLower.h" +#include "InstPrinter/MBlazeInstPrinter.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Target/Mangler.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include + +using namespace llvm; + +namespace { + class MBlazeAsmPrinter : public AsmPrinter { + const MBlazeSubtarget *Subtarget; + public: + explicit MBlazeAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) + : AsmPrinter(TM, Streamer) { + Subtarget = &TM.getSubtarget(); + } + + virtual const char *getPassName() const { + return "MBlaze Assembly Printer"; + } + + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant, const char *ExtraCode, + raw_ostream &O); + void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O); + void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O); + void printFSLImm(const MachineInstr *MI, int opNum, raw_ostream &O); + void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, + const char *Modifier = 0); + void printSavedRegsBitmask(raw_ostream &OS); + + void emitFrameDirective(); + + void EmitInstruction(const MachineInstr *MI); + virtual void EmitFunctionBodyStart(); + virtual void EmitFunctionBodyEnd(); + + virtual void EmitFunctionEntryLabel(); + }; +} // end of anonymous namespace + +// #include "MBlazeGenAsmWriter.inc" + +//===----------------------------------------------------------------------===// +// +// MBlaze Asm Directives +// +// -- Frame directive "frame Stackpointer, Stacksize, RARegister" +// Describe the stack frame. +// +// -- Mask directives "mask bitmask, offset" +// Tells the assembler which registers are saved and where. +// bitmask - contain a little endian bitset indicating which registers are +// saved on function prologue (e.g. with a 0x80000000 mask, the +// assembler knows the register 31 (RA) is saved at prologue. +// offset - the position before stack pointer subtraction indicating where +// the first saved register on prologue is located. (e.g. with a +// +// Consider the following function prologue: +// +// .frame R19,48,R15 +// .mask 0xc0000000,-8 +// addiu R1, R1, -48 +// sw R15, 40(R1) +// sw R19, 36(R1) +// +// With a 0xc0000000 mask, the assembler knows the register 15 (R15) and +// 19 (R19) are saved at prologue. As the save order on prologue is from +// left to right, R15 is saved first. A -8 offset means that after the +// stack pointer subtration, the first register in the mask (R15) will be +// saved at address 48-8=40. +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +void MBlazeAsmPrinter::EmitInstruction(const MachineInstr *MI) { + MBlazeMCInstLower MCInstLowering(OutContext, *Mang, *this); + + MCInst TmpInst; + MCInstLowering.Lower(MI, TmpInst); + OutStreamer.EmitInstruction(TmpInst); +} + +//===----------------------------------------------------------------------===// +// Mask directives +//===----------------------------------------------------------------------===// + +// Print a 32 bit hex number with all numbers. +static void printHex32(unsigned int Value, raw_ostream &O) { + O << "0x"; + for (int i = 7; i >= 0; i--) + O << utohexstr((Value & (0xF << (i*4))) >> (i*4)); +} + + +// Create a bitmask with all callee saved registers for CPU or Floating Point +// registers. For CPU registers consider RA, GP and FP for saving if necessary. +void MBlazeAsmPrinter::printSavedRegsBitmask(raw_ostream &O) { + const TargetRegisterInfo &RI = *TM.getRegisterInfo(); + const MBlazeFunctionInfo *MBlazeFI = MF->getInfo(); + + // CPU Saved Registers Bitmasks + unsigned int CPUBitmask = 0; + + // Set the CPU Bitmasks + const MachineFrameInfo *MFI = MF->getFrameInfo(); + const std::vector &CSI = MFI->getCalleeSavedInfo(); + for (unsigned i = 0, e = CSI.size(); i != e; ++i) { + unsigned Reg = CSI[i].getReg(); + unsigned RegNum = MBlazeRegisterInfo::getRegisterNumbering(Reg); + if (MBlaze::CPURegsRegisterClass->contains(Reg)) + CPUBitmask |= (1 << RegNum); + } + + // Return Address and Frame registers must also be set in CPUBitmask. + if (RI.hasFP(*MF)) + CPUBitmask |= (1 << MBlazeRegisterInfo:: + getRegisterNumbering(RI.getFrameRegister(*MF))); + + if (MFI->adjustsStack()) + CPUBitmask |= (1 << MBlazeRegisterInfo:: + getRegisterNumbering(RI.getRARegister())); + + // Print CPUBitmask + O << "\t.mask \t"; printHex32(CPUBitmask, O); + O << ',' << MBlazeFI->getCPUTopSavedRegOff() << '\n'; +} + +//===----------------------------------------------------------------------===// +// Frame and Set directives +//===----------------------------------------------------------------------===// + +/// Frame Directive +void MBlazeAsmPrinter::emitFrameDirective() { + // const TargetRegisterInfo &RI = *TM.getRegisterInfo(); + + // unsigned stackReg = RI.getFrameRegister(*MF); + // unsigned returnReg = RI.getRARegister(); + // unsigned stackSize = MF->getFrameInfo()->getStackSize(); + + + /* + OutStreamer.EmitRawText("\t.frame\t" + + Twine(MBlazeInstPrinter::getRegisterName(stackReg)) + + "," + Twine(stackSize) + "," + + Twine(MBlazeInstPrinter::getRegisterName(returnReg))); + */ +} + +void MBlazeAsmPrinter::EmitFunctionEntryLabel() { + // OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName())); + OutStreamer.EmitLabel(CurrentFnSym); +} + +/// EmitFunctionBodyStart - Targets can override this to emit stuff before +/// the first basic block in the function. +void MBlazeAsmPrinter::EmitFunctionBodyStart() { + // emitFrameDirective(); + + // SmallString<128> Str; + // raw_svector_ostream OS(Str); + // printSavedRegsBitmask(OS); + // OutStreamer.EmitRawText(OS.str()); +} + +/// EmitFunctionBodyEnd - Targets can override this to emit stuff after +/// the last basic block in the function. +void MBlazeAsmPrinter::EmitFunctionBodyEnd() { + // OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName())); +} + +// Print out an operand for an inline asm expression. +bool MBlazeAsmPrinter:: +PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, + unsigned AsmVariant,const char *ExtraCode, raw_ostream &O) { + // Does this asm operand have a single letter operand modifier? + if (ExtraCode && ExtraCode[0]) + return true; // Unknown modifier. + + printOperand(MI, OpNo, O); + return false; +} + +void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum, + raw_ostream &O) { + const MachineOperand &MO = MI->getOperand(opNum); + + switch (MO.getType()) { + case MachineOperand::MO_Register: + O << MBlazeInstPrinter::getRegisterName(MO.getReg()); + break; + + case MachineOperand::MO_Immediate: + O << (int)MO.getImm(); + break; + + case MachineOperand::MO_FPImmediate: { + const ConstantFP *fp = MO.getFPImm(); + printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue(), O); + O << ";\t# immediate = " << *fp; + break; + } + + case MachineOperand::MO_MachineBasicBlock: + O << *MO.getMBB()->getSymbol(); + return; + + case MachineOperand::MO_GlobalAddress: + O << *Mang->getSymbol(MO.getGlobal()); + break; + + case MachineOperand::MO_ExternalSymbol: + O << *GetExternalSymbolSymbol(MO.getSymbolName()); + break; + + case MachineOperand::MO_JumpTableIndex: + O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + << '_' << MO.getIndex(); + break; + + case MachineOperand::MO_ConstantPoolIndex: + O << MAI->getPrivateGlobalPrefix() << "CPI" + << getFunctionNumber() << "_" << MO.getIndex(); + if (MO.getOffset()) + O << "+" << MO.getOffset(); + break; + + default: + llvm_unreachable(""); + } +} + +void MBlazeAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum, + raw_ostream &O) { + const MachineOperand &MO = MI->getOperand(opNum); + if (MO.isImm()) + O << (unsigned int)MO.getImm(); + else + printOperand(MI, opNum, O); +} + +void MBlazeAsmPrinter::printFSLImm(const MachineInstr *MI, int opNum, + raw_ostream &O) { + const MachineOperand &MO = MI->getOperand(opNum); + if (MO.isImm()) + O << "rfsl" << (unsigned int)MO.getImm(); + else + printOperand(MI, opNum, O); +} + +void MBlazeAsmPrinter:: +printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O, + const char *Modifier) { + printOperand(MI, opNum+1, O); + O << ", "; + printOperand(MI, opNum, O); +} + +static MCInstPrinter *createMBlazeMCInstPrinter(const Target &T, + unsigned SyntaxVariant, + const MCAsmInfo &MAI) { + if (SyntaxVariant == 0) + return new MBlazeInstPrinter(MAI); + return 0; +} + +// Force static initialization. +extern "C" void LLVMInitializeMBlazeAsmPrinter() { + RegisterAsmPrinter X(TheMBlazeTarget); + TargetRegistry::RegisterMCInstPrinter(TheMBlazeTarget, + createMBlazeMCInstPrinter); + +} diff --git a/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp b/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp index b551b79b291..be9de6d5a20 100644 --- a/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp +++ b/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp @@ -19,6 +19,10 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -51,6 +55,91 @@ namespace { char Filler::ID = 0; } // end of anonymous namespace +static bool hasImmInstruction( MachineBasicBlock::iterator &candidate ) { + // Any instruction with an immediate mode operand greater than + // 16-bits requires an implicit IMM instruction. + unsigned numOper = candidate->getNumOperands(); + for( unsigned op = 0; op < numOper; ++op ) { + if( candidate->getOperand(op).isImm() && + (candidate->getOperand(op).getImm() & 0xFFFFFFFFFFFF0000LL) != 0 ) + return true; + + // FIXME: we could probably check to see if the FP value happens + // to not need an IMM instruction. For now we just always + // assume that FP values always do. + if( candidate->getOperand(op).isFPImm() ) + return true; + } + + return false; +} + +static bool delayHasHazard( MachineBasicBlock::iterator &candidate, + MachineBasicBlock::iterator &slot ) { + + // Loop over all of the operands in the branch instruction + // and make sure that none of them are defined by the + // candidate instruction. + unsigned numOper = slot->getNumOperands(); + for( unsigned op = 0; op < numOper; ++op ) { + if( !slot->getOperand(op).isReg() || + !slot->getOperand(op).isUse() || + slot->getOperand(op).isImplicit() ) + continue; + + unsigned cnumOper = candidate->getNumOperands(); + for( unsigned cop = 0; cop < cnumOper; ++cop ) { + if( candidate->getOperand(cop).isReg() && + candidate->getOperand(cop).isDef() && + candidate->getOperand(cop).getReg() == + slot->getOperand(op).getReg() ) + return true; + } + } + + // There are no hazards between the two instructions + return false; +} + +static bool usedBeforeDelaySlot( MachineBasicBlock::iterator &candidate, + MachineBasicBlock::iterator &slot ) { + MachineBasicBlock::iterator I = candidate; + for (++I; I != slot; ++I) { + unsigned numOper = I->getNumOperands(); + for( unsigned op = 0; op < numOper; ++op ) { + if( I->getOperand(op).isReg() && + I->getOperand(op).isUse() ) { + unsigned reg = I->getOperand(op).getReg(); + unsigned cops = candidate->getNumOperands(); + for( unsigned cop = 0; cop < cops; ++cop ) { + if( candidate->getOperand(cop).isReg() && + candidate->getOperand(cop).isDef() && + candidate->getOperand(cop).getReg() == reg ) + return true; + } + } + } + } + + return false; +} + +static MachineBasicBlock::iterator +findDelayInstr(MachineBasicBlock &MBB,MachineBasicBlock::iterator &slot) { + MachineBasicBlock::iterator found = MBB.end(); + for (MachineBasicBlock::iterator I = MBB.begin(); I != slot; ++I) { + TargetInstrDesc desc = I->getDesc(); + if( desc.hasDelaySlot() || desc.isBranch() || + desc.mayLoad() || desc. mayStore() || + hasImmInstruction(I) || delayHasHazard(I,slot) || + usedBeforeDelaySlot(I,slot)) continue; + + found = I; + } + + return found; +} + /// runOnMachineBasicBlock - Fill in delay slots for the given basic block. /// Currently, we fill delay slots with NOPs. We assume there is only one /// delay slot per delayed instruction. @@ -59,10 +148,16 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) if (I->getDesc().hasDelaySlot()) { MachineBasicBlock::iterator J = I; + MachineBasicBlock::iterator D = findDelayInstr(MBB,I); + ++J; - BuildMI(MBB, J, I->getDebugLoc(), TII->get(MBlaze::NOP)); ++FilledSlots; Changed = true; + + if( D == MBB.end() ) + BuildMI(MBB, J, I->getDebugLoc(), TII->get(MBlaze::NOP)); + else + MBB.splice( J, &MBB, D ); } return Changed; } diff --git a/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp b/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp new file mode 100644 index 00000000000..378b5d469fb --- /dev/null +++ b/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp @@ -0,0 +1,110 @@ +//===-- MBlazeELFWriterInfo.cpp - ELF Writer Info for the MBlaze backend --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements ELF writer information for the MBlaze backend. +// +//===----------------------------------------------------------------------===// + +#include "MBlazeELFWriterInfo.h" +#include "MBlazeRelocations.h" +#include "llvm/Function.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" + +using namespace llvm; + +//===----------------------------------------------------------------------===// +// Implementation of the MBlazeELFWriterInfo class +//===----------------------------------------------------------------------===// + +MBlazeELFWriterInfo::MBlazeELFWriterInfo(TargetMachine &TM) + : TargetELFWriterInfo(TM.getTargetData()->getPointerSizeInBits() == 64, + TM.getTargetData()->isLittleEndian()) { +} + +MBlazeELFWriterInfo::~MBlazeELFWriterInfo() {} + +unsigned MBlazeELFWriterInfo::getRelocationType(unsigned MachineRelTy) const { + switch(MachineRelTy) { + case MBlaze::reloc_pcrel_word: + return R_MICROBLAZE_64_PCREL; + case MBlaze::reloc_absolute_word: + return R_MICROBLAZE_NONE; + default: + llvm_unreachable("unknown mblaze machine relocation type"); + } + return 0; +} + +long int MBlazeELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, + long int Modifier) const { + switch(RelTy) { + case R_MICROBLAZE_32_PCREL: + return Modifier - 4; + case R_MICROBLAZE_32: + return Modifier; + default: + llvm_unreachable("unknown mblaze relocation type"); + } + return 0; +} + +unsigned MBlazeELFWriterInfo::getRelocationTySize(unsigned RelTy) const { + // FIXME: Most of these sizes are guesses based on the name + switch(RelTy) { + case R_MICROBLAZE_32: + case R_MICROBLAZE_32_PCREL: + case R_MICROBLAZE_32_PCREL_LO: + case R_MICROBLAZE_32_LO: + case R_MICROBLAZE_SRO32: + case R_MICROBLAZE_SRW32: + case R_MICROBLAZE_32_SYM_OP_SYM: + case R_MICROBLAZE_GOTOFF_32: + return 32; + + case R_MICROBLAZE_64_PCREL: + case R_MICROBLAZE_64: + case R_MICROBLAZE_GOTPC_64: + case R_MICROBLAZE_GOT_64: + case R_MICROBLAZE_PLT_64: + case R_MICROBLAZE_GOTOFF_64: + return 64; + } + + return 0; +} + +bool MBlazeELFWriterInfo::isPCRelativeRel(unsigned RelTy) const { + // FIXME: Most of these are guesses based on the name + switch(RelTy) { + case R_MICROBLAZE_32_PCREL: + case R_MICROBLAZE_64_PCREL: + case R_MICROBLAZE_32_PCREL_LO: + case R_MICROBLAZE_GOTPC_64: + return true; + } + + return false; +} + +unsigned MBlazeELFWriterInfo::getAbsoluteLabelMachineRelTy() const { + return MBlaze::reloc_absolute_word; +} + +long int MBlazeELFWriterInfo::computeRelocation(unsigned SymOffset, + unsigned RelOffset, + unsigned RelTy) const { + if (RelTy == R_MICROBLAZE_32_PCREL || R_MICROBLAZE_64_PCREL) + return SymOffset - (RelOffset + 4); + else + assert("computeRelocation unknown for this relocation type"); + + return 0; +} diff --git a/lib/Target/MBlaze/MBlazeELFWriterInfo.h b/lib/Target/MBlaze/MBlazeELFWriterInfo.h new file mode 100644 index 00000000000..2e6a9f3fa1b --- /dev/null +++ b/lib/Target/MBlaze/MBlazeELFWriterInfo.h @@ -0,0 +1,85 @@ +//===-- MBlazeELFWriterInfo.h - ELF Writer Info for MBlaze ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements ELF writer information for the MBlaze backend. +// +//===----------------------------------------------------------------------===// + +#ifndef MBLAZE_ELF_WRITER_INFO_H +#define MBLAZE_ELF_WRITER_INFO_H + +#include "llvm/Target/TargetELFWriterInfo.h" + +namespace llvm { + + class MBlazeELFWriterInfo : public TargetELFWriterInfo { + + // ELF Relocation types for MBlaze + enum MBlazeRelocationType { + R_MICROBLAZE_NONE = 0, + R_MICROBLAZE_32 = 1, + R_MICROBLAZE_32_PCREL = 2, + R_MICROBLAZE_64_PCREL = 3, + R_MICROBLAZE_32_PCREL_LO = 4, + R_MICROBLAZE_64 = 5, + R_MICROBLAZE_32_LO = 6, + R_MICROBLAZE_SRO32 = 7, + R_MICROBLAZE_SRW32 = 8, + R_MICROBLAZE_64_NONE = 9, + R_MICROBLAZE_32_SYM_OP_SYM = 10, + R_MICROBLAZE_GNU_VTINHERIT = 11, + R_MICROBLAZE_GNU_VTENTRY = 12, + R_MICROBLAZE_GOTPC_64 = 13, + R_MICROBLAZE_GOT_64 = 14, + R_MICROBLAZE_PLT_64 = 15, + R_MICROBLAZE_REL = 16, + R_MICROBLAZE_JUMP_SLOT = 17, + R_MICROBLAZE_GLOB_DAT = 18, + R_MICROBLAZE_GOTOFF_64 = 19, + R_MICROBLAZE_GOTOFF_32 = 20, + R_MICROBLAZE_COPY = 21 + }; + + public: + MBlazeELFWriterInfo(TargetMachine &TM); + virtual ~MBlazeELFWriterInfo(); + + /// getRelocationType - Returns the target specific ELF Relocation type. + /// 'MachineRelTy' contains the object code independent relocation type + virtual unsigned getRelocationType(unsigned MachineRelTy) const; + + /// hasRelocationAddend - True if the target uses an addend in the + /// ELF relocation entry. + virtual bool hasRelocationAddend() const { return false; } + + /// getDefaultAddendForRelTy - Gets the default addend value for a + /// relocation entry based on the target ELF relocation type. + virtual long int getDefaultAddendForRelTy(unsigned RelTy, + long int Modifier = 0) const; + + /// getRelTySize - Returns the size of relocatable field in bits + virtual unsigned getRelocationTySize(unsigned RelTy) const; + + /// isPCRelativeRel - True if the relocation type is pc relative + virtual bool isPCRelativeRel(unsigned RelTy) const; + + /// getJumpTableRelocationTy - Returns the machine relocation type used + /// to reference a jumptable. + virtual unsigned getAbsoluteLabelMachineRelTy() const; + + /// computeRelocation - Some relocatable fields could be relocated + /// directly, avoiding the relocation symbol emission, compute the + /// final relocation value for this symbol. + virtual long int computeRelocation(unsigned SymOffset, unsigned RelOffset, + unsigned RelTy) const; + }; + +} // end llvm namespace + +#endif // MBLAZE_ELF_WRITER_INFO_H diff --git a/lib/Target/MBlaze/MBlazeFixupKinds.h b/lib/Target/MBlaze/MBlazeFixupKinds.h new file mode 100644 index 00000000000..72466ca6ebe --- /dev/null +++ b/lib/Target/MBlaze/MBlazeFixupKinds.h @@ -0,0 +1,24 @@ +//===-- MBlaze/MBlazeFixupKinds.h - MBlaze Fixup Entries --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MBLAZE_MBLAZEFIXUPKINDS_H +#define LLVM_MBLAZE_MBLAZEFIXUPKINDS_H + +#include "llvm/MC/MCFixup.h" + +namespace llvm { +namespace MBlaze { +enum Fixups { + reloc_pcrel_4byte = FirstTargetFixupKind, // 32-bit pcrel, e.g. a brlid + reloc_pcrel_2byte // 16-bit pcrel, e.g. beqid +}; +} +} + +#endif diff --git a/lib/Target/MBlaze/MBlazeISelLowering.cpp b/lib/Target/MBlaze/MBlazeISelLowering.cpp index aca5f5d7476..822960937b3 100644 --- a/lib/Target/MBlaze/MBlazeISelLowering.cpp +++ b/lib/Target/MBlaze/MBlazeISelLowering.cpp @@ -421,13 +421,11 @@ LowerJumpTable(SDValue Op, SelectionDAG &DAG) const { SDValue HiPart; // FIXME there isn't actually debug info here DebugLoc dl = Op.getDebugLoc(); - bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_; - unsigned char OpFlag = IsPIC ? MBlazeII::MO_GOT : MBlazeII::MO_ABS_HILO; EVT PtrVT = Op.getValueType(); JumpTableSDNode *JT = cast(Op); - SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, OpFlag); + SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, 0 ); return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, JTI); //return JTI; } @@ -440,7 +438,7 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) const { DebugLoc dl = Op.getDebugLoc(); SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(), - N->getOffset(), MBlazeII::MO_ABS_HILO); + N->getOffset(), 0 ); return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, CP); } @@ -618,13 +616,12 @@ LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv, // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol // node so that legalize doesn't hack it. - unsigned char OpFlag = MBlazeII::MO_NO_FLAG; if (GlobalAddressSDNode *G = dyn_cast(Callee)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, - getPointerTy(), 0, OpFlag); + getPointerTy(), 0, 0 ); else if (ExternalSymbolSDNode *S = dyn_cast(Callee)) Callee = DAG.getTargetExternalSymbol(S->getSymbol(), - getPointerTy(), OpFlag); + getPointerTy(), 0 ); // MBlazeJmpLink = #chain, #target_address, #opt_in_flags... // = Chain, Callee, Reg#1, Reg#2, ... diff --git a/lib/Target/MBlaze/MBlazeInstrFPU.td b/lib/Target/MBlaze/MBlazeInstrFPU.td index 657b1d4940a..d9845bbc2b8 100644 --- a/lib/Target/MBlaze/MBlazeInstrFPU.td +++ b/lib/Target/MBlaze/MBlazeInstrFPU.td @@ -24,9 +24,9 @@ class LoadFM op, string instr_asm, PatFrag OpNode> : [(set FGR32:$dst, (OpNode xaddr:$addr))], IILoad>; class LoadFMI op, string instr_asm, PatFrag OpNode> : - TAI; + TB; class StoreFM op, string instr_asm, PatFrag OpNode> : TA op, string instr_asm, PatFrag OpNode> : [(OpNode FGR32:$dst, xaddr:$addr)], IIStore>; class StoreFMI op, string instr_asm, PatFrag OpNode> : - TAI; + TB; class ArithF op, bits<11> flags, string instr_asm, SDNode OpNode, InstrItinClass itin> : @@ -56,35 +56,35 @@ class ArithFR op, bits<11> flags, string instr_asm, SDNode OpNode, !strconcat(instr_asm, " $dst, $c, $b"), [(set FGR32:$dst, (OpNode FGR32:$b, FGR32:$c))], itin>; -class ArithF2 op, bits<11> flags, string instr_asm, - InstrItinClass itin> : - TF; - -class ArithIF op, bits<11> flags, string instr_asm, - InstrItinClass itin> : - TF; - -class ArithFI op, bits<11> flags, string instr_asm, - InstrItinClass itin> : - TF; - class LogicF op, string instr_asm> : - TAI; + TB; class LogicFI op, string instr_asm> : - TAI; + TB; + +let rb=0 in { + class ArithF2 op, bits<11> flags, string instr_asm, + InstrItinClass itin> : + TA; + + class ArithIF op, bits<11> flags, string instr_asm, + InstrItinClass itin> : + TA; + + class ArithFI op, bits<11> flags, string instr_asm, + InstrItinClass itin> : + TA; +} //===----------------------------------------------------------------------===// // Pseudo instructions diff --git a/lib/Target/MBlaze/MBlazeInstrFSL.td b/lib/Target/MBlaze/MBlazeInstrFSL.td index 51584111e66..f3c1cc32303 100644 --- a/lib/Target/MBlaze/MBlazeInstrFSL.td +++ b/lib/Target/MBlaze/MBlazeInstrFSL.td @@ -10,144 +10,208 @@ //===----------------------------------------------------------------------===// // FSL Instruction Formats //===----------------------------------------------------------------------===// -class FSLGetD op, bits<11> flags, string instr_asm, Intrinsic OpNode> : - TA; - -class FSLGet op, string instr_asm, Intrinsic OpNode> : - TAI; - -class FSLPutD op, bits<11> flags, string instr_asm, Intrinsic OpNode> : - TA; - -class FSLPut op, string instr_asm, Intrinsic OpNode> : - TAI; - -class FSLPutTD op, bits<11> flags, string instr_asm, Intrinsic OpNode> : - TA; - -class FSLPutT op, string instr_asm, Intrinsic OpNode> : - TAI; +class FSLGet op, bits<5> flags, string instr_asm, Intrinsic OpNode> : + MBlazeInst +{ + bits<5> rd; + bits<4> fslno; + + let Inst{6-10} = rd; + let Inst{11-15} = 0x0; + let Inst{16} = 0x0; + let Inst{17-21} = flags; // NCTAE + let Inst{22-27} = 0x0; + let Inst{28-31} = fslno; +} + +class FSLGetD op, bits<5> flags, string instr_asm, Intrinsic OpNode> : + MBlazeInst +{ + bits<5> rd; + bits<5> rb; + + let Inst{6-10} = rd; + let Inst{11-15} = 0x0; + let Inst{16-20} = rb; + let Inst{21} = 0x0; + let Inst{22-26} = flags; // NCTAE + let Inst{27-31} = 0x0; +} + +class FSLPut op, bits<4> flags, string instr_asm, Intrinsic OpNode> : + MBlazeInst +{ + bits<5> ra; + bits<4> fslno; + + let Inst{6-10} = 0x0; + let Inst{11-15} = ra; + let Inst{16} = 0x1; + let Inst{17-20} = flags; // NCTA + let Inst{21-27} = 0x0; + let Inst{28-31} = fslno; +} + +class FSLPutD op, bits<4> flags, string instr_asm, Intrinsic OpNode> : + MBlazeInst +{ + bits<5> ra; + bits<5> rb; + + let Inst{6-10} = 0x0; + let Inst{11-15} = ra; + let Inst{16-20} = rb; + let Inst{21} = 0x1; + let Inst{22-25} = flags; // NCTA + let Inst{26-31} = 0x0; +} + +class FSLPutT op, bits<4> flags, string instr_asm, Intrinsic OpNode> : + MBlazeInst +{ + bits<4> fslno; + + let Inst{6-10} = 0x0; + let Inst{11-15} = 0x0; + let Inst{16} = 0x1; + let Inst{17-20} = flags; // NCTA + let Inst{21-27} = 0x0; + let Inst{28-31} = fslno; +} + +class FSLPutTD op, bits<4> flags, string instr_asm, Intrinsic OpNode> : + MBlazeInst +{ + bits<5> rb; + + let Inst{6-10} = 0x0; + let Inst{11-15} = 0x0; + let Inst{16-20} = rb; + let Inst{21} = 0x1; + let Inst{22-25} = flags; // NCTA + let Inst{26-31} = 0x0; +} //===----------------------------------------------------------------------===// // FSL Get Instructions //===----------------------------------------------------------------------===// -def GET : FSLGet<0x1B, "get ", int_mblaze_fsl_get>; -def AGET : FSLGet<0x1B, "aget ", int_mblaze_fsl_aget>; -def CGET : FSLGet<0x1B, "cget ", int_mblaze_fsl_cget>; -def CAGET : FSLGet<0x1B, "caget ", int_mblaze_fsl_caget>; -def EGET : FSLGet<0x1B, "eget ", int_mblaze_fsl_eget>; -def EAGET : FSLGet<0x1B, "eaget ", int_mblaze_fsl_eaget>; -def ECGET : FSLGet<0x1B, "ecget ", int_mblaze_fsl_ecget>; -def ECAGET : FSLGet<0x1B, "ecaget ", int_mblaze_fsl_ecaget>; -def NGET : FSLGet<0x1B, "nget ", int_mblaze_fsl_nget>; -def NAGET : FSLGet<0x1B, "naget ", int_mblaze_fsl_naget>; -def NCGET : FSLGet<0x1B, "ncget ", int_mblaze_fsl_ncget>; -def NCAGET : FSLGet<0x1B, "ncaget ", int_mblaze_fsl_ncaget>; -def NEGET : FSLGet<0x1B, "neget ", int_mblaze_fsl_neget>; -def NEAGET : FSLGet<0x1B, "neaget ", int_mblaze_fsl_neaget>; -def NECGET : FSLGet<0x1B, "necget ", int_mblaze_fsl_necget>; -def NECAGET : FSLGet<0x1B, "necaget ", int_mblaze_fsl_necaget>; -def TGET : FSLGet<0x1B, "tget ", int_mblaze_fsl_tget>; -def TAGET : FSLGet<0x1B, "taget ", int_mblaze_fsl_taget>; -def TCGET : FSLGet<0x1B, "tcget ", int_mblaze_fsl_tcget>; -def TCAGET : FSLGet<0x1B, "tcaget ", int_mblaze_fsl_tcaget>; -def TEGET : FSLGet<0x1B, "teget ", int_mblaze_fsl_teget>; -def TEAGET : FSLGet<0x1B, "teaget ", int_mblaze_fsl_teaget>; -def TECGET : FSLGet<0x1B, "tecget ", int_mblaze_fsl_tecget>; -def TECAGET : FSLGet<0x1B, "tecaget ", int_mblaze_fsl_tecaget>; -def TNGET : FSLGet<0x1B, "tnget ", int_mblaze_fsl_tnget>; -def TNAGET : FSLGet<0x1B, "tnaget ", int_mblaze_fsl_tnaget>; -def TNCGET : FSLGet<0x1B, "tncget ", int_mblaze_fsl_tncget>; -def TNCAGET : FSLGet<0x1B, "tncaget ", int_mblaze_fsl_tncaget>; -def TNEGET : FSLGet<0x1B, "tneget ", int_mblaze_fsl_tneget>; -def TNEAGET : FSLGet<0x1B, "tneaget ", int_mblaze_fsl_tneaget>; -def TNECGET : FSLGet<0x1B, "tnecget ", int_mblaze_fsl_tnecget>; -def TNECAGET : FSLGet<0x1B, "tnecaget ", int_mblaze_fsl_tnecaget>; +def GET : FSLGet<0x1B, 0x00, "get ", int_mblaze_fsl_get>; +def AGET : FSLGet<0x1B, 0x02, "aget ", int_mblaze_fsl_aget>; +def CGET : FSLGet<0x1B, 0x08, "cget ", int_mblaze_fsl_cget>; +def CAGET : FSLGet<0x1B, 0x0A, "caget ", int_mblaze_fsl_caget>; +def EGET : FSLGet<0x1B, 0x01, "eget ", int_mblaze_fsl_eget>; +def EAGET : FSLGet<0x1B, 0x03, "eaget ", int_mblaze_fsl_eaget>; +def ECGET : FSLGet<0x1B, 0x09, "ecget ", int_mblaze_fsl_ecget>; +def ECAGET : FSLGet<0x1B, 0x0B, "ecaget ", int_mblaze_fsl_ecaget>; +def NGET : FSLGet<0x1B, 0x10, "nget ", int_mblaze_fsl_nget>; +def NAGET : FSLGet<0x1B, 0x12, "naget ", int_mblaze_fsl_naget>; +def NCGET : FSLGet<0x1B, 0x18, "ncget ", int_mblaze_fsl_ncget>; +def NCAGET : FSLGet<0x1B, 0x1A, "ncaget ", int_mblaze_fsl_ncaget>; +def NEGET : FSLGet<0x1B, 0x11, "neget ", int_mblaze_fsl_neget>; +def NEAGET : FSLGet<0x1B, 0x13, "neaget ", int_mblaze_fsl_neaget>; +def NECGET : FSLGet<0x1B, 0x19, "necget ", int_mblaze_fsl_necget>; +def NECAGET : FSLGet<0x1B, 0x1B, "necaget ", int_mblaze_fsl_necaget>; +def TGET : FSLGet<0x1B, 0x04, "tget ", int_mblaze_fsl_tget>; +def TAGET : FSLGet<0x1B, 0x06, "taget ", int_mblaze_fsl_taget>; +def TCGET : FSLGet<0x1B, 0x0C, "tcget ", int_mblaze_fsl_tcget>; +def TCAGET : FSLGet<0x1B, 0x0E, "tcaget ", int_mblaze_fsl_tcaget>; +def TEGET : FSLGet<0x1B, 0x05, "teget ", int_mblaze_fsl_teget>; +def TEAGET : FSLGet<0x1B, 0x07, "teaget ", int_mblaze_fsl_teaget>; +def TECGET : FSLGet<0x1B, 0x0D, "tecget ", int_mblaze_fsl_tecget>; +def TECAGET : FSLGet<0x1B, 0x0F, "tecaget ", int_mblaze_fsl_tecaget>; +def TNGET : FSLGet<0x1B, 0x14, "tnget ", int_mblaze_fsl_tnget>; +def TNAGET : FSLGet<0x1B, 0x16, "tnaget ", int_mblaze_fsl_tnaget>; +def TNCGET : FSLGet<0x1B, 0x1C, "tncget ", int_mblaze_fsl_tncget>; +def TNCAGET : FSLGet<0x1B, 0x1E, "tncaget ", int_mblaze_fsl_tncaget>; +def TNEGET : FSLGet<0x1B, 0x15, "tneget ", int_mblaze_fsl_tneget>; +def TNEAGET : FSLGet<0x1B, 0x17, "tneaget ", int_mblaze_fsl_tneaget>; +def TNECGET : FSLGet<0x1B, 0x1D, "tnecget ", int_mblaze_fsl_tnecget>; +def TNECAGET : FSLGet<0x1B, 0x1F, "tnecaget ", int_mblaze_fsl_tnecaget>; //===----------------------------------------------------------------------===// // FSL Dynamic Get Instructions //===----------------------------------------------------------------------===// -def GETD : FSLGetD<0x1B, 0x00, "getd ", int_mblaze_fsl_get>; -def AGETD : FSLGetD<0x1B, 0x00, "agetd ", int_mblaze_fsl_aget>; -def CGETD : FSLGetD<0x1B, 0x00, "cgetd ", int_mblaze_fsl_cget>; -def CAGETD : FSLGetD<0x1B, 0x00, "cagetd ", int_mblaze_fsl_caget>; -def EGETD : FSLGetD<0x1B, 0x00, "egetd ", int_mblaze_fsl_eget>; -def EAGETD : FSLGetD<0x1B, 0x00, "eagetd ", int_mblaze_fsl_eaget>; -def ECGETD : FSLGetD<0x1B, 0x00, "ecgetd ", int_mblaze_fsl_ecget>; -def ECAGETD : FSLGetD<0x1B, 0x00, "ecagetd ", int_mblaze_fsl_ecaget>; -def NGETD : FSLGetD<0x1B, 0x00, "ngetd ", int_mblaze_fsl_nget>; -def NAGETD : FSLGetD<0x1B, 0x00, "nagetd ", int_mblaze_fsl_naget>; -def NCGETD : FSLGetD<0x1B, 0x00, "ncgetd ", int_mblaze_fsl_ncget>; -def NCAGETD : FSLGetD<0x1B, 0x00, "ncagetd ", int_mblaze_fsl_ncaget>; -def NEGETD : FSLGetD<0x1B, 0x00, "negetd ", int_mblaze_fsl_neget>; -def NEAGETD : FSLGetD<0x1B, 0x00, "neagetd ", int_mblaze_fsl_neaget>; -def NECGETD : FSLGetD<0x1B, 0x00, "necgetd ", int_mblaze_fsl_necget>; -def NECAGETD : FSLGetD<0x1B, 0x00, "necagetd ", int_mblaze_fsl_necaget>; -def TGETD : FSLGetD<0x1B, 0x00, "tgetd ", int_mblaze_fsl_tget>; -def TAGETD : FSLGetD<0x1B, 0x00, "tagetd ", int_mblaze_fsl_taget>; -def TCGETD : FSLGetD<0x1B, 0x00, "tcgetd ", int_mblaze_fsl_tcget>; -def TCAGETD : FSLGetD<0x1B, 0x00, "tcagetd ", int_mblaze_fsl_tcaget>; -def TEGETD : FSLGetD<0x1B, 0x00, "tegetd ", int_mblaze_fsl_teget>; -def TEAGETD : FSLGetD<0x1B, 0x00, "teagetd ", int_mblaze_fsl_teaget>; -def TECGETD : FSLGetD<0x1B, 0x00, "tecgetd ", int_mblaze_fsl_tecget>; -def TECAGETD : FSLGetD<0x1B, 0x00, "tecagetd ", int_mblaze_fsl_tecaget>; -def TNGETD : FSLGetD<0x1B, 0x00, "tngetd ", int_mblaze_fsl_tnget>; -def TNAGETD : FSLGetD<0x1B, 0x00, "tnagetd ", int_mblaze_fsl_tnaget>; -def TNCGETD : FSLGetD<0x1B, 0x00, "tncgetd ", int_mblaze_fsl_tncget>; -def TNCAGETD : FSLGetD<0x1B, 0x00, "tncagetd ", int_mblaze_fsl_tncaget>; -def TNEGETD : FSLGetD<0x1B, 0x00, "tnegetd ", int_mblaze_fsl_tneget>; -def TNEAGETD : FSLGetD<0x1B, 0x00, "tneagetd ", int_mblaze_fsl_tneaget>; -def TNECGETD : FSLGetD<0x1B, 0x00, "tnecgetd ", int_mblaze_fsl_tnecget>; -def TNECAGETD : FSLGetD<0x1B, 0x00, "tnecagetd", int_mblaze_fsl_tnecaget>; +def GETD : FSLGetD<0x13, 0x00, "getd ", int_mblaze_fsl_get>; +def AGETD : FSLGetD<0x13, 0x02, "agetd ", int_mblaze_fsl_aget>; +def CGETD : FSLGetD<0x13, 0x08, "cgetd ", int_mblaze_fsl_cget>; +def CAGETD : FSLGetD<0x13, 0x0A, "cagetd ", int_mblaze_fsl_caget>; +def EGETD : FSLGetD<0x13, 0x01, "egetd ", int_mblaze_fsl_eget>; +def EAGETD : FSLGetD<0x13, 0x03, "eagetd ", int_mblaze_fsl_eaget>; +def ECGETD : FSLGetD<0x13, 0x09, "ecgetd ", int_mblaze_fsl_ecget>; +def ECAGETD : FSLGetD<0x13, 0x0B, "ecagetd ", int_mblaze_fsl_ecaget>; +def NGETD : FSLGetD<0x13, 0x10, "ngetd ", int_mblaze_fsl_nget>; +def NAGETD : FSLGetD<0x13, 0x12, "nagetd ", int_mblaze_fsl_naget>; +def NCGETD : FSLGetD<0x13, 0x18, "ncgetd ", int_mblaze_fsl_ncget>; +def NCAGETD : FSLGetD<0x13, 0x1A, "ncagetd ", int_mblaze_fsl_ncaget>; +def NEGETD : FSLGetD<0x13, 0x11, "negetd ", int_mblaze_fsl_neget>; +def NEAGETD : FSLGetD<0x13, 0x13, "neagetd ", int_mblaze_fsl_neaget>; +def NECGETD : FSLGetD<0x13, 0x19, "necgetd ", int_mblaze_fsl_necget>; +def NECAGETD : FSLGetD<0x13, 0x1B, "necagetd ", int_mblaze_fsl_necaget>; +def TGETD : FSLGetD<0x13, 0x04, "tgetd ", int_mblaze_fsl_tget>; +def TAGETD : FSLGetD<0x13, 0x06, "tagetd ", int_mblaze_fsl_taget>; +def TCGETD : FSLGetD<0x13, 0x0C, "tcgetd ", int_mblaze_fsl_tcget>; +def TCAGETD : FSLGetD<0x13, 0x0E, "tcagetd ", int_mblaze_fsl_tcaget>; +def TEGETD : FSLGetD<0x13, 0x05, "tegetd ", int_mblaze_fsl_teget>; +def TEAGETD : FSLGetD<0x13, 0x07, "teagetd ", int_mblaze_fsl_teaget>; +def TECGETD : FSLGetD<0x13, 0x0D, "tecgetd ", int_mblaze_fsl_tecget>; +def TECAGETD : FSLGetD<0x13, 0x0F, "tecagetd ", int_mblaze_fsl_tecaget>; +def TNGETD : FSLGetD<0x13, 0x14, "tngetd ", int_mblaze_fsl_tnget>; +def TNAGETD : FSLGetD<0x13, 0x16, "tnagetd ", int_mblaze_fsl_tnaget>; +def TNCGETD : FSLGetD<0x13, 0x1C, "tncgetd ", int_mblaze_fsl_tncget>; +def TNCAGETD : FSLGetD<0x13, 0x1E, "tncagetd ", int_mblaze_fsl_tncaget>; +def TNEGETD : FSLGetD<0x13, 0x15, "tnegetd ", int_mblaze_fsl_tneget>; +def TNEAGETD : FSLGetD<0x13, 0x17, "tneagetd ", int_mblaze_fsl_tneaget>; +def TNECGETD : FSLGetD<0x13, 0x1D, "tnecgetd ", int_mblaze_fsl_tnecget>; +def TNECAGETD : FSLGetD<0x13, 0x1F, "tnecagetd", int_mblaze_fsl_tnecaget>; //===----------------------------------------------------------------------===// // FSL Put Instructions //===----------------------------------------------------------------------===// -def PUT : FSLPut<0x1B, "put ", int_mblaze_fsl_put>; -def APUT : FSLPut<0x1B, "aput ", int_mblaze_fsl_aput>; -def CPUT : FSLPut<0x1B, "cput ", int_mblaze_fsl_cput>; -def CAPUT : FSLPut<0x1B, "caput ", int_mblaze_fsl_caput>; -def NPUT : FSLPut<0x1B, "nput ", int_mblaze_fsl_nput>; -def NAPUT : FSLPut<0x1B, "naput ", int_mblaze_fsl_naput>; -def NCPUT : FSLPut<0x1B, "ncput ", int_mblaze_fsl_ncput>; -def NCAPUT : FSLPut<0x1B, "ncaput ", int_mblaze_fsl_ncaput>; -def TPUT : FSLPutT<0x1B, "tput ", int_mblaze_fsl_tput>; -def TAPUT : FSLPutT<0x1B, "taput ", int_mblaze_fsl_taput>; -def TCPUT : FSLPutT<0x1B, "tcput ", int_mblaze_fsl_tcput>; -def TCAPUT : FSLPutT<0x1B, "tcaput ", int_mblaze_fsl_tcaput>; -def TNPUT : FSLPutT<0x1B, "tnput ", int_mblaze_fsl_tnput>; -def TNAPUT : FSLPutT<0x1B, "tnaput ", int_mblaze_fsl_tnaput>; -def TNCPUT : FSLPutT<0x1B, "tncput ", int_mblaze_fsl_tncput>; -def TNCAPUT : FSLPutT<0x1B, "tncaput ", int_mblaze_fsl_tncaput>; +def PUT : FSLPut<0x1B, 0x0, "put ", int_mblaze_fsl_put>; +def APUT : FSLPut<0x1B, 0x1, "aput ", int_mblaze_fsl_aput>; +def CPUT : FSLPut<0x1B, 0x4, "cput ", int_mblaze_fsl_cput>; +def CAPUT : FSLPut<0x1B, 0x5, "caput ", int_mblaze_fsl_caput>; +def NPUT : FSLPut<0x1B, 0x8, "nput ", int_mblaze_fsl_nput>; +def NAPUT : FSLPut<0x1B, 0x9, "naput ", int_mblaze_fsl_naput>; +def NCPUT : FSLPut<0x1B, 0xC, "ncput ", int_mblaze_fsl_ncput>; +def NCAPUT : FSLPut<0x1B, 0xD, "ncaput ", int_mblaze_fsl_ncaput>; +def TPUT : FSLPutT<0x1B, 0x2, "tput ", int_mblaze_fsl_tput>; +def TAPUT : FSLPutT<0x1B, 0x3, "taput ", int_mblaze_fsl_taput>; +def TCPUT : FSLPutT<0x1B, 0x6, "tcput ", int_mblaze_fsl_tcput>; +def TCAPUT : FSLPutT<0x1B, 0x7, "tcaput ", int_mblaze_fsl_tcaput>; +def TNPUT : FSLPutT<0x1B, 0xA, "tnput ", int_mblaze_fsl_tnput>; +def TNAPUT : FSLPutT<0x1B, 0xB, "tnaput ", int_mblaze_fsl_tnaput>; +def TNCPUT : FSLPutT<0x1B, 0xE, "tncput ", int_mblaze_fsl_tncput>; +def TNCAPUT : FSLPutT<0x1B, 0xF, "tncaput ", int_mblaze_fsl_tncaput>; //===----------------------------------------------------------------------===// // FSL Dynamic Put Instructions //===----------------------------------------------------------------------===// -def PUTD : FSLPutD<0x1B, 0x00, "putd ", int_mblaze_fsl_put>; -def APUTD : FSLPutD<0x1B, 0x00, "aputd ", int_mblaze_fsl_aput>; -def CPUTD : FSLPutD<0x1B, 0x00, "cputd ", int_mblaze_fsl_cput>; -def CAPUTD : FSLPutD<0x1B, 0x00, "caputd ", int_mblaze_fsl_caput>; -def NPUTD : FSLPutD<0x1B, 0x00, "nputd ", int_mblaze_fsl_nput>; -def NAPUTD : FSLPutD<0x1B, 0x00, "naputd ", int_mblaze_fsl_naput>; -def NCPUTD : FSLPutD<0x1B, 0x00, "ncputd ", int_mblaze_fsl_ncput>; -def NCAPUTD : FSLPutD<0x1B, 0x00, "ncaputd ", int_mblaze_fsl_ncaput>; -def TPUTD : FSLPutTD<0x1B, 0x00, "tputd ", int_mblaze_fsl_tput>; -def TAPUTD : FSLPutTD<0x1B, 0x00, "taputd ", int_mblaze_fsl_taput>; -def TCPUTD : FSLPutTD<0x1B, 0x00, "tcputd ", int_mblaze_fsl_tcput>; -def TCAPUTD : FSLPutTD<0x1B, 0x00, "tcaputd ", int_mblaze_fsl_tcaput>; -def TNPUTD : FSLPutTD<0x1B, 0x00, "tnputd ", int_mblaze_fsl_tnput>; -def TNAPUTD : FSLPutTD<0x1B, 0x00, "tnaputd ", int_mblaze_fsl_tnaput>; -def TNCPUTD : FSLPutTD<0x1B, 0x00, "tncputd ", int_mblaze_fsl_tncput>; -def TNCAPUTD : FSLPutTD<0x1B, 0x00, "tncaputd ", int_mblaze_fsl_tncaput>; +def PUTD : FSLPutD<0x13, 0x0, "putd ", int_mblaze_fsl_put>; +def APUTD : FSLPutD<0x13, 0x1, "aputd ", int_mblaze_fsl_aput>; +def CPUTD : FSLPutD<0x13, 0x4, "cputd ", int_mblaze_fsl_cput>; +def CAPUTD : FSLPutD<0x13, 0x5, "caputd ", int_mblaze_fsl_caput>; +def NPUTD : FSLPutD<0x13, 0x8, "nputd ", int_mblaze_fsl_nput>; +def NAPUTD : FSLPutD<0x13, 0x9, "naputd ", int_mblaze_fsl_naput>; +def NCPUTD : FSLPutD<0x13, 0xC, "ncputd ", int_mblaze_fsl_ncput>; +def NCAPUTD : FSLPutD<0x13, 0xD, "ncaputd ", int_mblaze_fsl_ncaput>; +def TPUTD : FSLPutTD<0x13, 0x2, "tputd ", int_mblaze_fsl_tput>; +def TAPUTD : FSLPutTD<0x13, 0x3, "taputd ", int_mblaze_fsl_taput>; +def TCPUTD : FSLPutTD<0x13, 0x6, "tcputd ", int_mblaze_fsl_tcput>; +def TCAPUTD : FSLPutTD<0x13, 0x7, "tcaputd ", int_mblaze_fsl_tcaput>; +def TNPUTD : FSLPutTD<0x13, 0xA, "tnputd ", int_mblaze_fsl_tnput>; +def TNAPUTD : FSLPutTD<0x13, 0xB, "tnaputd ", int_mblaze_fsl_tnaput>; +def TNCPUTD : FSLPutTD<0x13, 0xE, "tncputd ", int_mblaze_fsl_tncput>; +def TNCAPUTD : FSLPutTD<0x13, 0xF, "tncaputd ", int_mblaze_fsl_tncaput>; diff --git a/lib/Target/MBlaze/MBlazeInstrFormats.td b/lib/Target/MBlaze/MBlazeInstrFormats.td index 28e8e440222..595ef1da611 100644 --- a/lib/Target/MBlaze/MBlazeInstrFormats.td +++ b/lib/Target/MBlaze/MBlazeInstrFormats.td @@ -7,6 +7,26 @@ // //===----------------------------------------------------------------------===// +// Format specifies the encoding used by the instruction. This is part of the +// ad-hoc solution used to emit machine instruction encodings by our machine +// code emitter. +class Format val> { + bits<6> Value = val; +} + +def FPseudo : Format<0>; +def FRRR : Format<1>; +def FRRI : Format<2>; +def FRIR : Format<3>; +def FFSL : Format<4>; +def FFSLD : Format<5>; +def FFSLT : Format<6>; +def FFSLTD : Format<7>; +def FR : Format<8>; +def FI : Format<9>; +def FRR : Format<10>; +def FRI : Format<11>; + //===----------------------------------------------------------------------===// // Describe MBlaze instructions format // @@ -21,14 +41,15 @@ //===----------------------------------------------------------------------===// // Generic MBlaze Format -class MBlazeInst pattern, - InstrItinClass itin> : Instruction +class MBlazeInst op, Format form, dag outs, dag ins, string asmstr, + list pattern, InstrItinClass itin> : Instruction { - field bits<32> Inst; - let Namespace = "MBlaze"; + field bits<32> Inst; - bits<6> opcode; + bits<6> opcode = op; + Format Form = form; + bits<6> FormBits = Form.Value; // Top 6 bits are the 'opcode' field let Inst{0-5} = opcode; @@ -39,13 +60,16 @@ class MBlazeInst pattern, let AsmString = asmstr; let Pattern = pattern; let Itinerary = itin; + + // TSFlags layout should be kept in sync with MBlazeInstrInfo.h. + let TSFlags{5-0} = FormBits; } //===----------------------------------------------------------------------===// // Pseudo instruction class //===----------------------------------------------------------------------===// class MBlazePseudo pattern>: - MBlazeInst; + MBlazeInst<0x0, FPseudo, outs, ins, asmstr, pattern, IIPseudo>; //===----------------------------------------------------------------------===// // Type A instruction class in MBlaze : <|opcode|rd|ra|rb|flags|> @@ -53,194 +77,49 @@ class MBlazePseudo pattern>: class TA op, bits<11> flags, dag outs, dag ins, string asmstr, list pattern, InstrItinClass itin> : - MBlazeInst + MBlazeInst { bits<5> rd; bits<5> ra; bits<5> rb; - let opcode = op; - let Inst{6-10} = rd; let Inst{11-15} = ra; let Inst{16-20} = rb; let Inst{21-31} = flags; } -class TAI op, dag outs, dag ins, string asmstr, - list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<5> rd; - bits<5> ra; - bits<16> imm16; - - let opcode = op; - - let Inst{6-10} = rd; - let Inst{11-15} = ra; - let Inst{16-31} = imm16; -} - -class TIMM op, dag outs, dag ins, string asmstr, - list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<5> ra; - bits<16> imm16; - - let opcode = op; - - let Inst{6-15} = 0; - let Inst{16-31} = imm16; -} - -class TADDR op, dag outs, dag ins, string asmstr, - list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<26> addr; - - let opcode = op; - - let Inst{6-31} = addr; -} - //===----------------------------------------------------------------------===// // Type B instruction class in MBlaze : <|opcode|rd|ra|immediate|> //===----------------------------------------------------------------------===// class TB op, dag outs, dag ins, string asmstr, list pattern, InstrItinClass itin> : - MBlazeInst + MBlazeInst { bits<5> rd; bits<5> ra; bits<16> imm16; - let opcode = op; - let Inst{6-10} = rd; let Inst{11-15} = ra; let Inst{16-31} = imm16; } //===----------------------------------------------------------------------===// -// Float instruction class in MBlaze : <|opcode|rd|ra|flags|> +// Type B instruction class in MBlaze but with the operands reversed in +// the LLVM DAG : <|opcode|rd|ra|immediate|> //===----------------------------------------------------------------------===// +class TBR op, dag outs, dag ins, string asmstr, list pattern, + InstrItinClass itin> : + TB { + bits<5> rrd; + bits<16> rimm16; + bits<5> rra; -class TF op, bits<11> flags, dag outs, dag ins, string asmstr, - list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<5> rd; - bits<5> ra; - - let opcode = op; - - let Inst{6-10} = rd; - let Inst{11-15} = ra; - let Inst{16-20} = 0; - let Inst{21-31} = flags; -} - -//===----------------------------------------------------------------------===// -// Branch instruction class in MBlaze : <|opcode|rd|br|ra|flags|> -//===----------------------------------------------------------------------===// - -class TBR op, bits<5> br, bits<11> flags, dag outs, dag ins, - string asmstr, list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<5> ra; - - let opcode = op; - - let Inst{6-10} = 0; - let Inst{11-15} = br; - let Inst{16-20} = ra; - let Inst{21-31} = flags; -} - -class TBRC op, bits<5> br, bits<11> flags, dag outs, dag ins, - string asmstr, list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<5> ra; - bits<5> rb; - - let opcode = op; - - let Inst{6-10} = br; - let Inst{11-15} = ra; - let Inst{16-20} = rb; - let Inst{21-31} = flags; -} - -class TBRL op, bits<5> br, bits<11> flags, dag outs, dag ins, - string asmstr, list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<5> ra; - - let opcode = op; - - let Inst{6-10} = 0xF; - let Inst{11-15} = br; - let Inst{16-20} = ra; - let Inst{21-31} = flags; -} - -class TBRI op, bits<5> br, dag outs, dag ins, - string asmstr, list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<16> imm16; - - let opcode = op; - - let Inst{6-10} = 0; - let Inst{11-15} = br; - let Inst{16-31} = imm16; -} - -class TBRLI op, bits<5> br, dag outs, dag ins, - string asmstr, list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<16> imm16; - - let opcode = op; - - let Inst{6-10} = 0xF; - let Inst{11-15} = br; - let Inst{16-31} = imm16; -} - -class TBRCI op, bits<5> br, dag outs, dag ins, - string asmstr, list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<5> ra; - bits<16> imm16; - - let opcode = op; - - let Inst{6-10} = br; - let Inst{11-15} = ra; - let Inst{16-31} = imm16; -} - -class TRET op, dag outs, dag ins, - string asmstr, list pattern, InstrItinClass itin> : - MBlazeInst -{ - bits<5> ra; - bits<16> imm16; - - let opcode = op; + let Form = FRIR; - let Inst{6-10} = 0x10; - let Inst{11-15} = ra; - let Inst{16-31} = imm16; + let rd = rrd; + let ra = rra; + let imm16 = rimm16; } diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.h b/lib/Target/MBlaze/MBlazeInstrInfo.h index b3dba0ec768..eda16cc5e15 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.h +++ b/lib/Target/MBlaze/MBlazeInstrInfo.h @@ -134,29 +134,47 @@ namespace MBlaze { /// instruction info tracks. /// namespace MBlazeII { - /// Target Operand Flag enum. - enum TOF { + enum { + // PseudoFrm - This represents an instruction that is a pseudo instruction + // or one that has not been implemented yet. It is illegal to code generate + // it, but tolerated for intermediate implementation stages. + Pseudo = 0, + + RegRegReg = 1, + RegRegImm = 2, + RegImmReg = 3, + FSL = 4, + FSLD = 5, + FSLT = 6, + FSLTD = 7, + Reg = 8, + Imm = 9, + RegReg = 10, + RegImm = 11, + + FormMask = 63 + //===------------------------------------------------------------------===// // MBlaze Specific MachineOperand flags. - MO_NO_FLAG, + // MO_NO_FLAG, /// MO_GOT - Represents the offset into the global offset table at which /// the address the relocation entry symbol resides during execution. - MO_GOT, + // MO_GOT, /// MO_GOT_CALL - Represents the offset into the global offset table at /// which the address of a call site relocation entry symbol resides /// during execution. This is different from the above since this flag /// can only be present in call instructions. - MO_GOT_CALL, + // MO_GOT_CALL, /// MO_GPREL - Represents the offset from the current gp value to be used /// for the relocatable object file being produced. - MO_GPREL, + // MO_GPREL, /// MO_ABS_HILO - Represents the hi or low part of an absolute symbol /// address. - MO_ABS_HILO + // MO_ABS_HILO }; } diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td index e5d153474a7..41c80efaab1 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.td +++ b/lib/Target/MBlaze/MBlazeInstrInfo.td @@ -13,36 +13,33 @@ include "MBlazeInstrFormats.td" //===----------------------------------------------------------------------===// -// MBlaze profiles and nodes +// MBlaze type profiles //===----------------------------------------------------------------------===// + +// def SDTMBlazeSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>; def SDT_MBlazeRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>; def SDT_MBlazeJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; +def SDT_MBCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; +def SDT_MBCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; -// Call -def MBlazeJmpLink : SDNode<"MBlazeISD::JmpLink",SDT_MBlazeJmpLink, - [SDNPHasChain,SDNPOptInFlag,SDNPOutFlag]>; +//===----------------------------------------------------------------------===// +// MBlaze specific nodes +//===----------------------------------------------------------------------===// -// Return -def MBlazeRet : SDNode<"MBlazeISD::Ret", SDT_MBlazeRet, +def MBlazeRet : SDNode<"MBlazeISD::Ret", SDT_MBlazeRet, [SDNPHasChain, SDNPOptInFlag]>; -// Hi and Lo nodes are used to handle global addresses. Used on -// MBlazeISelLowering to lower stuff like GlobalAddress, ExternalSymbol -// static model. -def MBWrapper : SDNode<"MBlazeISD::Wrap", SDTIntUnaryOp>; -def MBlazeGPRel : SDNode<"MBlazeISD::GPRel", SDTIntUnaryOp>; +def MBlazeJmpLink : SDNode<"MBlazeISD::JmpLink",SDT_MBlazeJmpLink, + [SDNPHasChain,SDNPOptInFlag,SDNPOutFlag]>; -def SDT_MBCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>; -def SDT_MBCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>; +def MBWrapper : SDNode<"MBlazeISD::Wrap", SDTIntUnaryOp>; -// These are target-independent nodes, but have target-specific formats. def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MBCallSeqStart, [SDNPHasChain, SDNPOutFlag]>; + def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MBCallSeqEnd, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; -def SDTMBlazeSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>; - //===----------------------------------------------------------------------===// // MBlaze Instruction Predicate Definitions. //===----------------------------------------------------------------------===// @@ -95,18 +92,7 @@ def memrr : Operand { let MIOperandInfo = (ops CPURegs, CPURegs); } -// Transformation Function - get the lower 16 bits. -def LO16 : SDNodeXFormgetZExtValue() & 0xFFFF); -}]>; - -// Transformation Function - get the higher 16 bits. -def HI16 : SDNodeXFormgetZExtValue() >> 16); -}]>; - // Node immediate fits as 16-bit sign extended on target immediate. -// e.g. addi, andi def immSExt16 : PatLeaf<(imm), [{ return (N->getZExtValue() >> 16) == 0; }]>; @@ -117,19 +103,19 @@ def immSExt16 : PatLeaf<(imm), [{ // e.g. addiu, sltiu def immZExt16 : PatLeaf<(imm), [{ return (N->getZExtValue() >> 16) == 0; -}], LO16>; +}]>; // FSL immediate field must fit in 4 bits. def immZExt4 : PatLeaf<(imm), [{ - return N->getZExtValue() == ((N->getZExtValue()) & 0xf) ; + return N->getZExtValue() == ((N->getZExtValue()) & 0xf) ; }]>; // shamt field must fit in 5 bits. def immZExt5 : PatLeaf<(imm), [{ - return N->getZExtValue() == ((N->getZExtValue()) & 0x1f) ; + return N->getZExtValue() == ((N->getZExtValue()) & 0x1f) ; }]>; -// MBlaze Address Mode! SDNode frameindex could possibily be a match +// MBlaze Address Mode. SDNode frameindex could possibily be a match // since load and store instructions from stack used it. def iaddr : ComplexPattern; def xaddr : ComplexPattern; @@ -141,28 +127,14 @@ def xaddr : ComplexPattern; // As stack alignment is always done with addiu, we need a 16-bit immediate let Defs = [R1], Uses = [R1] in { def ADJCALLSTACKDOWN : MBlazePseudo<(outs), (ins simm16:$amt), - "${:comment} ADJCALLSTACKDOWN $amt", + "#ADJCALLSTACKDOWN $amt", [(callseq_start timm:$amt)]>; def ADJCALLSTACKUP : MBlazePseudo<(outs), (ins uimm16:$amt1, simm16:$amt2), - "${:comment} ADJCALLSTACKUP $amt1", + "#ADJCALLSTACKUP $amt1", [(callseq_end timm:$amt1, timm:$amt2)]>; } -// Some assembly macros need to avoid pseudoinstructions and assembler -// automatic reodering, we should reorder ourselves. -def MACRO : MBlazePseudo<(outs), (ins), ".set macro", []>; -def REORDER : MBlazePseudo<(outs), (ins), ".set reorder", []>; -def NOMACRO : MBlazePseudo<(outs), (ins), ".set nomacro", []>; -def NOREORDER : MBlazePseudo<(outs), (ins), ".set noreorder", []>; - -// When handling PIC code the assembler needs .cpload and .cprestore -// directives. If the real instructions corresponding these directives -// are used, we have the same behavior, but get also a bunch of warnings -// from the assembler. -def CPLOAD : MBlazePseudo<(outs), (ins CPURegs:$reg), ".cpload $reg", []>; -def CPRESTORE : MBlazePseudo<(outs), (ins uimm16:$l), ".cprestore $l\n", []>; - //===----------------------------------------------------------------------===// // Instructions specific format //===----------------------------------------------------------------------===// @@ -178,19 +150,19 @@ class Arith op, bits<11> flags, string instr_asm, SDNode OpNode, class ArithI op, string instr_asm, SDNode OpNode, Operand Od, PatLeaf imm_type> : - TAI; + TB; class ArithR op, bits<11> flags, string instr_asm, SDNode OpNode, InstrItinClass itin> : TA; + !strconcat(instr_asm, " $dst, $c, $b"), + [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>; class ArithRI op, string instr_asm, SDNode OpNode, Operand Od, PatLeaf imm_type> : - TAI; @@ -201,9 +173,9 @@ class ArithN op, bits<11> flags, string instr_asm, [], itin>; class ArithNI op, string instr_asm,Operand Od, PatLeaf imm_type> : - TAI; + TB; class ArithRN op, bits<11> flags, string instr_asm, InstrItinClass itin> : @@ -212,9 +184,9 @@ class ArithRN op, bits<11> flags, string instr_asm, [], itin>; class ArithRNI op, string instr_asm,Operand Od, PatLeaf imm_type> : - TAI; + TB; //===----------------------------------------------------------------------===// // Misc Arithmetic Instructions @@ -226,14 +198,10 @@ class Logic op, bits<11> flags, string instr_asm, SDNode OpNode> : [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], IIAlu>; class LogicI op, string instr_asm, SDNode OpNode> : - TAI; - -class EffectiveAddress : - TAI<0x08, (outs CPURegs:$dst), (ins memri:$addr), - instr_asm, [(set CPURegs:$dst, iaddr:$addr)], IIAlu>; + TB; //===----------------------------------------------------------------------===// // Memory Access Instructions @@ -244,7 +212,7 @@ class LoadM op, string instr_asm, PatFrag OpNode> : [(set CPURegs:$dst, (OpNode xaddr:$addr))], IILoad>; class LoadMI op, string instr_asm, PatFrag OpNode> : - TAI; @@ -254,7 +222,7 @@ class StoreM op, string instr_asm, PatFrag OpNode> : [(OpNode CPURegs:$dst, xaddr:$addr)], IIStore>; class StoreMI op, string instr_asm, PatFrag OpNode> : - TAI; @@ -262,94 +230,108 @@ class StoreMI op, string instr_asm, PatFrag OpNode> : // Branch Instructions //===----------------------------------------------------------------------===// class Branch op, bits<5> br, bits<11> flags, string instr_asm> : - TBR; + [], IIBranch> { + let rd = 0x0; + let ra = br; +} -class BranchI op, bits<5> brf, string instr_asm> : - TBRI; +class BranchI op, bits<5> br, string instr_asm> : + TB { + let rd = 0; + let ra = br; +} //===----------------------------------------------------------------------===// // Branch and Link Instructions //===----------------------------------------------------------------------===// class BranchL op, bits<5> br, bits<11> flags, string instr_asm> : - TBRL; + TA { + let rd = 15; + let ra = br; +} class BranchLI op, bits<5> br, string instr_asm> : - TBRLI; + TB { + let rd = 15; + let ra = br; +} //===----------------------------------------------------------------------===// // Conditional Branch Instructions //===----------------------------------------------------------------------===// class BranchC op, bits<5> br, bits<11> flags, string instr_asm, PatFrag cond_op> : - TBRC; - //(brcond (cond_op CPURegs:$a, CPURegs:$b), bb:$offset)], - //IIBranch>; + TA { + let rd = br; +} class BranchCI op, bits<5> br, string instr_asm, PatFrag cond_op> : - TBRCI; + TB { + let rd = br; +} //===----------------------------------------------------------------------===// // MBlaze arithmetic instructions //===----------------------------------------------------------------------===// let isCommutable = 1, isAsCheapAsAMove = 1 in { - def ADD : Arith<0x00, 0x000, "add ", add, IIAlu>; - def ADDC : Arith<0x02, 0x000, "addc ", adde, IIAlu>; - def ADDK : Arith<0x04, 0x000, "addk ", addc, IIAlu>; - def ADDKC : ArithN<0x06, 0x000, "addkc ", IIAlu>; - def AND : Logic<0x21, 0x000, "and ", and>; - def OR : Logic<0x20, 0x000, "or ", or>; - def XOR : Logic<0x22, 0x000, "xor ", xor>; + def ADD : Arith<0x00, 0x000, "add ", add, IIAlu>; + def ADDC : Arith<0x02, 0x000, "addc ", adde, IIAlu>; + def ADDK : Arith<0x04, 0x000, "addk ", addc, IIAlu>; + def ADDKC : ArithN<0x06, 0x000, "addkc ", IIAlu>; + def AND : Logic<0x21, 0x000, "and ", and>; + def OR : Logic<0x20, 0x000, "or ", or>; + def XOR : Logic<0x22, 0x000, "xor ", xor>; } let isAsCheapAsAMove = 1 in { - def ANDN : ArithN<0x23, 0x000, "andn ", IIAlu>; - def CMP : ArithN<0x05, 0x001, "cmp ", IIAlu>; - def CMPU : ArithN<0x05, 0x003, "cmpu ", IIAlu>; - def RSUB : ArithR<0x01, 0x000, "rsub ", sub, IIAlu>; - def RSUBC : ArithR<0x03, 0x000, "rsubc ", sube, IIAlu>; - def RSUBK : ArithR<0x05, 0x000, "rsubk ", subc, IIAlu>; - def RSUBKC : ArithRN<0x07, 0x000, "rsubkc ", IIAlu>; + def ANDN : ArithN<0x23, 0x000, "andn ", IIAlu>; + def CMP : ArithN<0x05, 0x001, "cmp ", IIAlu>; + def CMPU : ArithN<0x05, 0x003, "cmpu ", IIAlu>; + def RSUB : ArithR<0x01, 0x000, "rsub ", sub, IIAlu>; + def RSUBC : ArithR<0x03, 0x000, "rsubc ", sube, IIAlu>; + def RSUBK : ArithR<0x05, 0x000, "rsubk ", subc, IIAlu>; + def RSUBKC : ArithRN<0x07, 0x000, "rsubkc ", IIAlu>; } let isCommutable = 1, Predicates=[HasMul] in { - def MUL : Arith<0x10, 0x000, "mul ", mul, IIAlu>; + def MUL : Arith<0x10, 0x000, "mul ", mul, IIAlu>; } let isCommutable = 1, Predicates=[HasMul,HasMul64] in { - def MULH : Arith<0x10, 0x001, "mulh ", mulhs, IIAlu>; - def MULHU : Arith<0x10, 0x003, "mulhu ", mulhu, IIAlu>; + def MULH : Arith<0x10, 0x001, "mulh ", mulhs, IIAlu>; + def MULHU : Arith<0x10, 0x003, "mulhu ", mulhu, IIAlu>; } let Predicates=[HasMul,HasMul64] in { - def MULHSU : ArithN<0x10, 0x002, "mulhsu ", IIAlu>; + def MULHSU : ArithN<0x10, 0x002, "mulhsu ", IIAlu>; } let Predicates=[HasBarrel] in { - def BSRL : Arith<0x11, 0x000, "bsrl ", srl, IIAlu>; - def BSRA : Arith<0x11, 0x200, "bsra ", sra, IIAlu>; - def BSLL : Arith<0x11, 0x400, "bsll ", shl, IIAlu>; - def BSRLI : ArithI<0x11, "bsrli ", srl, uimm5, immZExt5>; - def BSRAI : ArithI<0x11, "bsrai ", sra, uimm5, immZExt5>; - def BSLLI : ArithI<0x11, "bslli ", shl, uimm5, immZExt5>; + def BSRL : Arith<0x11, 0x000, "bsrl ", srl, IIAlu>; + def BSRA : Arith<0x11, 0x200, "bsra ", sra, IIAlu>; + def BSLL : Arith<0x11, 0x400, "bsll ", shl, IIAlu>; + def BSRLI : ArithI<0x11, "bsrli ", srl, uimm5, immZExt5>; + def BSRAI : ArithI<0x11, "bsrai ", sra, uimm5, immZExt5>; + def BSLLI : ArithI<0x11, "bslli ", shl, uimm5, immZExt5>; } let Predicates=[HasDiv] in { - def IDIV : Arith<0x12, 0x000, "idiv ", sdiv, IIAlu>; - def IDIVU : Arith<0x12, 0x002, "idivu ", udiv, IIAlu>; + def IDIV : Arith<0x12, 0x000, "idiv ", sdiv, IIAlu>; + def IDIVU : Arith<0x12, 0x002, "idivu ", udiv, IIAlu>; } //===----------------------------------------------------------------------===// @@ -357,22 +339,22 @@ let Predicates=[HasDiv] in { //===----------------------------------------------------------------------===// let isAsCheapAsAMove = 1 in { - def ADDI : ArithI<0x08, "addi ", add, simm16, immSExt16>; - def ADDIC : ArithNI<0x0A, "addic ", simm16, immSExt16>; - def ADDIK : ArithNI<0x0C, "addik ", simm16, immSExt16>; - def ADDIKC : ArithI<0x0E, "addikc ", addc, simm16, immSExt16>; - def RSUBI : ArithRI<0x09, "rsubi ", sub, simm16, immSExt16>; - def RSUBIC : ArithRNI<0x0B, "rsubi ", simm16, immSExt16>; - def RSUBIK : ArithRNI<0x0E, "rsubic ", simm16, immSExt16>; - def RSUBIKC : ArithRI<0x0F, "rsubikc", subc, simm16, immSExt16>; - def ANDNI : ArithNI<0x2B, "andni ", uimm16, immZExt16>; - def ANDI : LogicI<0x29, "andi ", and>; - def ORI : LogicI<0x28, "ori ", or>; - def XORI : LogicI<0x2A, "xori ", xor>; + def ADDI : ArithI<0x08, "addi ", add, simm16, immSExt16>; + def ADDIC : ArithNI<0x0A, "addic ", simm16, immSExt16>; + def ADDIK : ArithNI<0x0C, "addik ", simm16, immSExt16>; + def ADDIKC : ArithI<0x0E, "addikc ", addc, simm16, immSExt16>; + def RSUBI : ArithRI<0x09, "rsubi ", sub, simm16, immSExt16>; + def RSUBIC : ArithRNI<0x0B, "rsubi ", simm16, immSExt16>; + def RSUBIK : ArithRNI<0x0E, "rsubic ", simm16, immSExt16>; + def RSUBIKC : ArithRI<0x0F, "rsubikc", subc, simm16, immSExt16>; + def ANDNI : ArithNI<0x2B, "andni ", uimm16, immZExt16>; + def ANDI : LogicI<0x29, "andi ", and>; + def ORI : LogicI<0x28, "ori ", or>; + def XORI : LogicI<0x2A, "xori ", xor>; } let Predicates=[HasMul] in { - def MULI : ArithI<0x18, "muli ", mul, simm16, immSExt16>; + def MULI : ArithI<0x18, "muli ", mul, simm16, immSExt16>; } //===----------------------------------------------------------------------===// @@ -380,115 +362,122 @@ let Predicates=[HasMul] in { //===----------------------------------------------------------------------===// let canFoldAsLoad = 1, isReMaterializable = 1 in { - def LBU : LoadM<0x30, "lbu ", zextloadi8>; - def LHU : LoadM<0x31, "lhu ", zextloadi16>; - def LW : LoadM<0x32, "lw ", load>; + def LBU : LoadM<0x30, "lbu ", zextloadi8>; + def LHU : LoadM<0x31, "lhu ", zextloadi16>; + def LW : LoadM<0x32, "lw ", load>; - def LBUI : LoadMI<0x30, "lbui ", zextloadi8>; - def LHUI : LoadMI<0x31, "lhui ", zextloadi16>; - def LWI : LoadMI<0x32, "lwi ", load>; + def LBUI : LoadMI<0x38, "lbui ", zextloadi8>; + def LHUI : LoadMI<0x39, "lhui ", zextloadi16>; + def LWI : LoadMI<0x3A, "lwi ", load>; } - def SB : StoreM<0x34, "sb ", truncstorei8>; - def SH : StoreM<0x35, "sh ", truncstorei16>; - def SW : StoreM<0x36, "sw ", store>; + def SB : StoreM<0x34, "sb ", truncstorei8>; + def SH : StoreM<0x35, "sh ", truncstorei16>; + def SW : StoreM<0x36, "sw ", store>; - def SBI : StoreMI<0x34, "sbi ", truncstorei8>; - def SHI : StoreMI<0x35, "shi ", truncstorei16>; - def SWI : StoreMI<0x36, "swi ", store>; + def SBI : StoreMI<0x3C, "sbi ", truncstorei8>; + def SHI : StoreMI<0x3D, "shi ", truncstorei16>; + def SWI : StoreMI<0x3E, "swi ", store>; //===----------------------------------------------------------------------===// // MBlaze branch instructions //===----------------------------------------------------------------------===// -let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { - def BRI : BranchI<0x2E, 0x00, "bri ">; - def BRAI : BranchI<0x2E, 0x08, "brai ">; - def BEQI : BranchCI<0x2F, 0x00, "beqi ", seteq>; - def BNEI : BranchCI<0x2F, 0x01, "bnei ", setne>; - def BLTI : BranchCI<0x2F, 0x02, "blti ", setlt>; - def BLEI : BranchCI<0x2F, 0x03, "blei ", setle>; - def BGTI : BranchCI<0x2F, 0x04, "bgti ", setgt>; - def BGEI : BranchCI<0x2F, 0x05, "bgei ", setge>; +let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1, + Form = FI in { + def BRI : BranchI<0x2E, 0x00, "bri ">; + def BRAI : BranchI<0x2E, 0x08, "brai ">; } -let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { - def BR : Branch<0x26, 0x00, 0x000, "br ">; - def BRA : Branch<0x26, 0x08, 0x000, "bra ">; - def BEQ : BranchC<0x27, 0x00, 0x000, "beq ", seteq>; - def BNE : BranchC<0x27, 0x01, 0x000, "bne ", setne>; - def BLT : BranchC<0x27, 0x02, 0x000, "blt ", setlt>; - def BLE : BranchC<0x27, 0x03, 0x000, "ble ", setle>; - def BGT : BranchC<0x27, 0x04, 0x000, "bgt ", setgt>; - def BGE : BranchC<0x27, 0x05, 0x000, "bge ", setge>; +let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, Form = FRI in { + def BEQI : BranchCI<0x2F, 0x00, "beqi ", seteq>; + def BNEI : BranchCI<0x2F, 0x01, "bnei ", setne>; + def BLTI : BranchCI<0x2F, 0x02, "blti ", setlt>; + def BLEI : BranchCI<0x2F, 0x03, "blei ", setle>; + def BGTI : BranchCI<0x2F, 0x04, "bgti ", setgt>; + def BGEI : BranchCI<0x2F, 0x05, "bgei ", setge>; } -let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1 in { - def BRID : BranchI<0x2E, 0x10, "brid ">; - def BRAID : BranchI<0x2E, 0x18, "braid ">; - def BEQID : BranchCI<0x2F, 0x10, "beqid ", seteq>; - def BNEID : BranchCI<0x2F, 0x11, "bneid ", setne>; - def BLTID : BranchCI<0x2F, 0x12, "bltid ", setlt>; - def BLEID : BranchCI<0x2F, 0x13, "bleid ", setle>; - def BGTID : BranchCI<0x2F, 0x14, "bgtid ", setgt>; - def BGEID : BranchCI<0x2F, 0x15, "bgeid ", setge>; +let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1, + isBarrier = 1, Form = FR in { + def BR : Branch<0x26, 0x00, 0x000, "br ">; + def BRA : Branch<0x26, 0x08, 0x000, "bra ">; +} + +let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1, + Form = FRR in { + def BEQ : BranchC<0x27, 0x00, 0x000, "beq ", seteq>; + def BNE : BranchC<0x27, 0x01, 0x000, "bne ", setne>; + def BLT : BranchC<0x27, 0x02, 0x000, "blt ", setlt>; + def BLE : BranchC<0x27, 0x03, 0x000, "ble ", setle>; + def BGT : BranchC<0x27, 0x04, 0x000, "bgt ", setgt>; + def BGE : BranchC<0x27, 0x05, 0x000, "bge ", setge>; +} + +let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1, + isBarrier = 1, Form = FI in { + def BRID : BranchI<0x2E, 0x10, "brid ">; + def BRAID : BranchI<0x2E, 0x18, "braid ">; +} + +let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1, + Form = FRI in { + def BEQID : BranchCI<0x2F, 0x10, "beqid ", seteq>; + def BNEID : BranchCI<0x2F, 0x11, "bneid ", setne>; + def BLTID : BranchCI<0x2F, 0x12, "bltid ", setlt>; + def BLEID : BranchCI<0x2F, 0x13, "bleid ", setle>; + def BGTID : BranchCI<0x2F, 0x14, "bgtid ", setgt>; + def BGEID : BranchCI<0x2F, 0x15, "bgeid ", setge>; +} + +let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, Form = FR, + hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1 in { + def BRD : Branch<0x26, 0x10, 0x000, "brd ">; + def BRAD : Branch<0x26, 0x18, 0x000, "brad ">; } let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, - hasDelaySlot = 1, hasCtrlDep = 1 in { - def BRD : Branch<0x26, 0x10, 0x000, "brd ">; - def BRAD : Branch<0x26, 0x18, 0x000, "brad ">; - def BEQD : BranchC<0x27, 0x10, 0x000, "beqd ", seteq>; - def BNED : BranchC<0x27, 0x11, 0x000, "bned ", setne>; - def BLTD : BranchC<0x27, 0x12, 0x000, "bltd ", setlt>; - def BLED : BranchC<0x27, 0x13, 0x000, "bled ", setle>; - def BGTD : BranchC<0x27, 0x14, 0x000, "bgtd ", setgt>; - def BGED : BranchC<0x27, 0x15, 0x000, "bged ", setge>; -} - -let isCall = 1, hasCtrlDep = 1, isIndirectBranch = 1, - Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12], - Uses = [R1,R5,R6,R7,R8,R9,R10] in { - def BRL : BranchL<0x26, 0x04, 0x000, "brl ">; - def BRAL : BranchL<0x26, 0x0C, 0x000, "bral ">; + hasDelaySlot = 1, hasCtrlDep = 1, Form = FRR in { + def BEQD : BranchC<0x27, 0x10, 0x000, "beqd ", seteq>; + def BNED : BranchC<0x27, 0x11, 0x000, "bned ", setne>; + def BLTD : BranchC<0x27, 0x12, 0x000, "bltd ", setlt>; + def BLED : BranchC<0x27, 0x13, 0x000, "bled ", setle>; + def BGTD : BranchC<0x27, 0x14, 0x000, "bgtd ", setgt>; + def BGED : BranchC<0x27, 0x15, 0x000, "bged ", setge>; } -let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, +let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1, Form = FI, Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12], Uses = [R1,R5,R6,R7,R8,R9,R10] in { - def BRLID : BranchLI<0x2E, 0x14, "brlid ">; - def BRALID : BranchLI<0x2E, 0x1C, "bralid ">; + def BRLID : BranchLI<0x2E, 0x14, "brlid ">; + def BRALID : BranchLI<0x2E, 0x1C, "bralid ">; } let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isIndirectBranch = 1, + isBarrier = 1, Form = FR, Defs = [R3,R4,R5,R6,R7,R8,R9,R10,R11,R12], Uses = [R1,R5,R6,R7,R8,R9,R10] in { - def BRLD : BranchL<0x26, 0x14, 0x000, "brld ">; - def BRALD : BranchL<0x26, 0x1C, 0x000, "brald ">; + def BRLD : BranchL<0x26, 0x14, 0x000, "brld ">; + def BRALD : BranchL<0x26, 0x1C, 0x000, "brald ">; } -let isReturn=1, isTerminator=1, hasDelaySlot=1, - isBarrier=1, hasCtrlDep=1, imm16=0x8 in { - def RTSD : TRET<0x2D, (outs), (ins CPURegs:$target), - "rtsd $target, 8", - [(MBlazeRet CPURegs:$target)], - IIBranch>; +let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, + hasCtrlDep=1, rd=0x10, imm16=0x8, Form=FR in { + def RTSD : TB<0x2D, (outs), (ins CPURegs:$target), + "rtsd $target, 8", + [(MBlazeRet CPURegs:$target)], + IIBranch>; } //===----------------------------------------------------------------------===// // MBlaze misc instructions //===----------------------------------------------------------------------===// -let addr = 0 in { - def NOP : TADDR<0x00, (outs), (ins), "nop ", [], IIAlu>; +let neverHasSideEffects = 1 in { + def NOP : MBlazeInst< 0x20, FRRR, (outs), (ins), "nop ", [], IIAlu>; } let usesCustomInserter = 1 in { - //class PseudoSelCC: - // MBlazePseudo<(outs RC:$D), (ins RC:$T, RC:$F, CPURegs:$CMP), asmstr, - // [(set RC:$D, (MBlazeSelectCC RC:$T, RC:$F, CPURegs:$CMP))]>; - //def Select_CC : PseudoSelCC; - def Select_CC : MBlazePseudo<(outs CPURegs:$dst), (ins CPURegs:$T, CPURegs:$F, CPURegs:$CMP, i32imm:$CC), "; SELECT_CC PSEUDO!", @@ -512,19 +501,23 @@ let usesCustomInserter = 1 in { let rb = 0 in { - def SEXT16 : TA<0x24, 0x061, (outs CPURegs:$dst), (ins CPURegs:$src), - "sext16 $dst, $src", [], IIAlu>; - def SEXT8 : TA<0x24, 0x060, (outs CPURegs:$dst), (ins CPURegs:$src), - "sext8 $dst, $src", [], IIAlu>; - def SRL : TA<0x24, 0x041, (outs CPURegs:$dst), (ins CPURegs:$src), - "srl $dst, $src", [], IIAlu>; - def SRA : TA<0x24, 0x001, (outs CPURegs:$dst), (ins CPURegs:$src), - "sra $dst, $src", [], IIAlu>; - def SRC : TA<0x24, 0x021, (outs CPURegs:$dst), (ins CPURegs:$src), - "src $dst, $src", [], IIAlu>; + def SEXT16 : TA<0x24, 0x061, (outs CPURegs:$dst), (ins CPURegs:$src), + "sext16 $dst, $src", [], IIAlu>; + def SEXT8 : TA<0x24, 0x060, (outs CPURegs:$dst), (ins CPURegs:$src), + "sext8 $dst, $src", [], IIAlu>; + def SRL : TA<0x24, 0x041, (outs CPURegs:$dst), (ins CPURegs:$src), + "srl $dst, $src", [], IIAlu>; + def SRA : TA<0x24, 0x001, (outs CPURegs:$dst), (ins CPURegs:$src), + "sra $dst, $src", [], IIAlu>; + def SRC : TA<0x24, 0x021, (outs CPURegs:$dst), (ins CPURegs:$src), + "src $dst, $src", [], IIAlu>; } -def LEA_ADDI : EffectiveAddress<"addi $dst, ${addr:stackloc}">; +let opcode=0x08 in { + def LEA_ADDI : TB<0x08, (outs CPURegs:$dst), (ins memri:$addr), + "addi $dst, ${addr:stackloc}", + [(set CPURegs:$dst, iaddr:$addr)], IIAlu>; +} //===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions @@ -610,6 +603,10 @@ def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETUGE), def : Pat<(selectcc CPURegs:$L, CPURegs:$R, CPURegs:$T, CPURegs:$F, SETULE), (Select_CC CPURegs:$T, CPURegs:$F, (CMPU CPURegs:$L, CPURegs:$R), 6)>; +// BR instructions +def : Pat<(br bb:$T), (BRID bb:$T)>; +def : Pat<(brind CPURegs:$T), (BRD CPURegs:$T)>; + // BRCOND instructions def : Pat<(brcond (setcc CPURegs:$L, CPURegs:$R, SETEQ), bb:$T), (BEQID (CMP CPURegs:$R, CPURegs:$L), bb:$T)>; diff --git a/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp b/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp new file mode 100644 index 00000000000..fec147decdf --- /dev/null +++ b/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp @@ -0,0 +1,235 @@ +//===-- MBlazeMCCodeEmitter.cpp - Convert MBlaze code to machine code -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the MBlazeMCCodeEmitter class. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "mblaze-emitter" +#include "MBlaze.h" +#include "MBlazeInstrInfo.h" +#include "MBlazeFixupKinds.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCFixup.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +STATISTIC(MCNumEmitted, "Number of MC instructions emitted"); + +namespace { +class MBlazeMCCodeEmitter : public MCCodeEmitter { + MBlazeMCCodeEmitter(const MBlazeMCCodeEmitter &); // DO NOT IMPLEMENT + void operator=(const MBlazeMCCodeEmitter &); // DO NOT IMPLEMENT + const TargetMachine &TM; + const TargetInstrInfo &TII; + MCContext &Ctx; + +public: + MBlazeMCCodeEmitter(TargetMachine &tm, MCContext &ctx) + : TM(tm), TII(*TM.getInstrInfo()), Ctx(ctx) { + } + + ~MBlazeMCCodeEmitter() {} + + // getBinaryCodeForInstr - TableGen'erated function for getting the + // binary encoding for an instruction. + unsigned getBinaryCodeForInstr(const MCInst &MI) const; + + /// getMachineOpValue - Return binary encoding of operand. If the machine + /// operand requires relocation, record the relocation and return zero. + unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO) const; + unsigned getMachineOpValue(const MCInst &MI, unsigned OpIdx) const { + return getMachineOpValue(MI, MI.getOperand(OpIdx)); + } + + unsigned getNumFixupKinds() const { + return 2; + } + + const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { + const static MCFixupKindInfo Infos[] = { + { "reloc_pcrel_4byte", 0, 4 * 8, MCFixupKindInfo::FKF_IsPCRel }, + { "reloc_pcrel_2byte", 0, 2 * 8, MCFixupKindInfo::FKF_IsPCRel } }; + + if (Kind < FirstTargetFixupKind) + return MCCodeEmitter::getFixupKindInfo(Kind); + + if (unsigned(Kind-FirstTargetFixupKind) < getNumFixupKinds()) + return Infos[Kind - FirstTargetFixupKind]; + + assert(0 && "Invalid fixup kind."); + return Infos[0]; + } + + static unsigned GetMBlazeRegNum(const MCOperand &MO) { + // FIXME: getMBlazeRegisterNumbering() is sufficient? + assert(0 && "MBlazeMCCodeEmitter::GetMBlazeRegNum() not yet implemented."); + return 0; + } + + void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const { + // The MicroBlaze uses a bit reversed format so we need to reverse the + // order of the bits. Taken from: + // http://graphics.stanford.edu/~seander/bithacks.html + C = ((C * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32; + + OS << (char)C; + ++CurByte; + } + + void EmitRawByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const { + OS << (char)C; + ++CurByte; + } + + void EmitConstant(uint64_t Val, unsigned Size, unsigned &CurByte, + raw_ostream &OS) const { + assert(Size <= 8 && "size too big in emit constant" ); + + for (unsigned i = 0; i != Size; ++i) { + EmitByte(Val & 255, CurByte, OS); + Val >>= 8; + } + } + + void EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const; + + void EmitImmediate(const MCInst &MI, + unsigned opNo, MCFixupKind FixupKind, + unsigned &CurByte, raw_ostream &OS, + SmallVectorImpl &Fixups) const; + + void EncodeInstruction(const MCInst &MI, raw_ostream &OS, + SmallVectorImpl &Fixups) const; +}; + +} // end anonymous namespace + + +MCCodeEmitter *llvm::createMBlazeMCCodeEmitter(const Target &, + TargetMachine &TM, + MCContext &Ctx) { + return new MBlazeMCCodeEmitter(TM, Ctx); +} + +/// getMachineOpValue - Return binary encoding of operand. If the machine +/// operand requires relocation, record the relocation and return zero. +unsigned MBlazeMCCodeEmitter::getMachineOpValue(const MCInst &MI, + const MCOperand &MO) const { + if (MO.isReg()) + return MBlazeRegisterInfo::getRegisterNumbering(MO.getReg()); + else if (MO.isImm()) + return static_cast(MO.getImm()); + else if (MO.isExpr() ) + return 0; // The relocation has already been recorded at this point. + else { +#ifndef NDEBUG + errs() << MO; +#endif + llvm_unreachable(0); + } + return 0; +} + +void MBlazeMCCodeEmitter:: +EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const { + int32_t val = (int32_t)imm.getImm(); + if (val > 32767 || val < -32678 ) { + EmitByte(0x0D, CurByte, OS); + EmitByte(0x00, CurByte, OS); + EmitRawByte((val >> 24) & 0xFF, CurByte, OS); + EmitRawByte((val >> 16) & 0xFF, CurByte, OS); + } +} + +void MBlazeMCCodeEmitter:: +EmitImmediate(const MCInst &MI, unsigned opNo, MCFixupKind FixupKind, + unsigned &CurByte, raw_ostream &OS, + SmallVectorImpl &Fixups) const { + assert( MI.getNumOperands()>opNo && "Not enought operands for instruction" ); + + MCOperand oper = MI.getOperand(opNo); + if (oper.isImm()) { + EmitIMM( oper, CurByte, OS ); + } else if (oper.isExpr()) { + Fixups.push_back(MCFixup::Create(0,oper.getExpr(),FixupKind)); + } +} + +void MBlazeMCCodeEmitter:: +EncodeInstruction(const MCInst &MI, raw_ostream &OS, + SmallVectorImpl &Fixups) const { + unsigned Opcode = MI.getOpcode(); + const TargetInstrDesc &Desc = TII.get(Opcode); + uint64_t TSFlags = Desc.TSFlags; + // Keep track of the current byte being emitted. + unsigned CurByte = 0; + + switch ((TSFlags & MBlazeII::FormMask)) { + default: break; + case MBlazeII::Pseudo: + // Pseudo instructions don't get encoded. + return; + + case MBlazeII::RegRegImm: + EmitImmediate( MI, 2, FK_Data_4, CurByte, OS, Fixups ); + break; + + case MBlazeII::RegImmReg: + EmitImmediate( MI, 1, FK_Data_4, CurByte, OS, Fixups ); + break; + + case MBlazeII::RegImm: + EmitImmediate( MI, 1, MCFixupKind(MBlaze::reloc_pcrel_2byte), CurByte, OS, + Fixups ); + break; + + case MBlazeII::Imm: + EmitImmediate( MI, 0, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS, + Fixups ); + break; + } + + ++MCNumEmitted; // Keep track of the # of mi's emitted + unsigned Value = getBinaryCodeForInstr(MI); + switch (Opcode) { + default: + EmitConstant(Value, 4, CurByte, OS); + break; + + case MBlaze::BRI: + case MBlaze::BRAI: + case MBlaze::BRID: + case MBlaze::BRAID: + case MBlaze::BRLID: + case MBlaze::BRALID: + MCOperand op = MI.getOperand(0); + if (op.isExpr()) { + EmitByte(0x0D, CurByte, OS); + EmitByte(0x00, CurByte, OS); + EmitRawByte(0, CurByte, OS); + EmitRawByte(0, CurByte, OS); + } + EmitConstant(Value, 4, CurByte, OS); + break; + } +} + +// FIXME: These #defines shouldn't be necessary. Instead, tblgen should +// be able to generate code emitter helpers for either variant, like it +// does for the AsmWriter. +#define MBlazeCodeEmitter MBlazeMCCodeEmitter +#define MachineInstr MCInst +#include "MBlazeGenCodeEmitter.inc" +#undef MBlazeCodeEmitter +#undef MachineInstr diff --git a/lib/Target/MBlaze/MBlazeMCInstLower.cpp b/lib/Target/MBlaze/MBlazeMCInstLower.cpp new file mode 100644 index 00000000000..f43916bf58d --- /dev/null +++ b/lib/Target/MBlaze/MBlazeMCInstLower.cpp @@ -0,0 +1,174 @@ +//===-- MBLazeMCInstLower.cpp - Convert MBlaze MachineInstr to an MCInst---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains code to lower MBlaze MachineInstrs to their corresponding +// MCInst records. +// +//===----------------------------------------------------------------------===// + +#include "MBLazeMCInstLower.h" +#include "MBlazeInstrInfo.h" +#include "llvm/Constants.h" +#include "llvm/CodeGen/AsmPrinter.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Target/Mangler.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/ADT/SmallString.h" +using namespace llvm; + +MCSymbol *MBlazeMCInstLower:: +GetGlobalAddressSymbol(const MachineOperand &MO) const { + switch (MO.getTargetFlags()) { + default: + llvm_unreachable("Unknown target flag on GV operand"); + + case 0: break; + } + + return Printer.Mang->getSymbol(MO.getGlobal()); +} + +MCSymbol *MBlazeMCInstLower:: +GetExternalSymbolSymbol(const MachineOperand &MO) const { + switch (MO.getTargetFlags()) { + default: + assert(0 && "Unknown target flag on GV operand"); + + case 0: break; + } + + return Printer.GetExternalSymbolSymbol(MO.getSymbolName()); +} + +MCSymbol *MBlazeMCInstLower:: +GetJumpTableSymbol(const MachineOperand &MO) const { + SmallString<256> Name; + raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI" + << Printer.getFunctionNumber() << '_' + << MO.getIndex(); + + switch (MO.getTargetFlags()) { + default: + llvm_unreachable("Unknown target flag on GV operand"); + + case 0: break; + } + + // Create a symbol for the name. + return Ctx.GetOrCreateSymbol(Name.str()); +} + +MCSymbol *MBlazeMCInstLower:: +GetConstantPoolIndexSymbol(const MachineOperand &MO) const { + SmallString<256> Name; + raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI" + << Printer.getFunctionNumber() << '_' + << MO.getIndex(); + + switch (MO.getTargetFlags()) { + default: + llvm_unreachable("Unknown target flag on GV operand"); + + case 0: break; + } + + // Create a symbol for the name. + return Ctx.GetOrCreateSymbol(Name.str()); +} + +MCSymbol *MBlazeMCInstLower:: +GetBlockAddressSymbol(const MachineOperand &MO) const { + switch (MO.getTargetFlags()) { + default: + assert(0 && "Unknown target flag on GV operand"); + + case 0: break; + } + + return Printer.GetBlockAddressSymbol(MO.getBlockAddress()); +} + +MCOperand MBlazeMCInstLower:: +LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const { + // FIXME: We would like an efficient form for this, so we don't have to do a + // lot of extra uniquing. + const MCExpr *Expr = MCSymbolRefExpr::Create(Sym, Ctx); + + switch (MO.getTargetFlags()) { + default: + llvm_unreachable("Unknown target flag on GV operand"); + + case 0: break; + } + + if (!MO.isJTI() && MO.getOffset()) + Expr = MCBinaryExpr::CreateAdd(Expr, + MCConstantExpr::Create(MO.getOffset(), Ctx), + Ctx); + return MCOperand::CreateExpr(Expr); +} + +void MBlazeMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { + OutMI.setOpcode(MI->getOpcode()); + + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + + MCOperand MCOp; + switch (MO.getType()) { + default: + assert(0 && "unknown operand type"); + case MachineOperand::MO_Register: + // Ignore all implicit register operands. + if (MO.isImplicit()) continue; + MCOp = MCOperand::CreateReg(MO.getReg()); + break; + case MachineOperand::MO_Immediate: + MCOp = MCOperand::CreateImm(MO.getImm()); + break; + case MachineOperand::MO_MachineBasicBlock: + MCOp = MCOperand::CreateExpr(MCSymbolRefExpr::Create( + MO.getMBB()->getSymbol(), Ctx)); + break; + case MachineOperand::MO_GlobalAddress: + MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); + break; + case MachineOperand::MO_ExternalSymbol: + MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); + break; + case MachineOperand::MO_JumpTableIndex: + MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO)); + break; + case MachineOperand::MO_ConstantPoolIndex: + MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); + break; + case MachineOperand::MO_BlockAddress: + MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO)); + break; + case MachineOperand::MO_FPImmediate: + bool ignored; + APFloat FVal = MO.getFPImm()->getValueAPF(); + FVal.convert(APFloat::IEEEsingle, APFloat::rmTowardZero, &ignored); + + APInt IVal = FVal.bitcastToAPInt(); + uint64_t Val = *IVal.getRawData(); + MCOp = MCOperand::CreateImm(Val); + break; + } + + OutMI.addOperand(MCOp); + } +} diff --git a/lib/Target/MBlaze/MBlazeMCInstLower.h b/lib/Target/MBlaze/MBlazeMCInstLower.h new file mode 100644 index 00000000000..92196f22022 --- /dev/null +++ b/lib/Target/MBlaze/MBlazeMCInstLower.h @@ -0,0 +1,50 @@ +//===-- MBlazeMCInstLower.h - Lower MachineInstr to MCInst ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef MBLAZE_MCINSTLOWER_H +#define MBLAZE_MCINSTLOWER_H + +#include "llvm/Support/Compiler.h" + +namespace llvm { + class AsmPrinter; + class MCAsmInfo; + class MCContext; + class MCInst; + class MCOperand; + class MCSymbol; + class MachineInstr; + class MachineModuleInfoMachO; + class MachineOperand; + class Mangler; + + /// MBlazeMCInstLower - This class is used to lower an MachineInstr + /// into an MCInst. +class LLVM_LIBRARY_VISIBILITY MBlazeMCInstLower { + MCContext &Ctx; + Mangler &Mang; + + AsmPrinter &Printer; +public: + MBlazeMCInstLower(MCContext &ctx, Mangler &mang, AsmPrinter &printer) + : Ctx(ctx), Mang(mang), Printer(printer) {} + void Lower(const MachineInstr *MI, MCInst &OutMI) const; + + MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const; + + MCSymbol *GetGlobalAddressSymbol(const MachineOperand &MO) const; + MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const; + MCSymbol *GetJumpTableSymbol(const MachineOperand &MO) const; + MCSymbol *GetConstantPoolIndexSymbol(const MachineOperand &MO) const; + MCSymbol *GetBlockAddressSymbol(const MachineOperand &MO) const; +}; + +} + +#endif diff --git a/lib/Target/MBlaze/MBlazeRelocations.h b/lib/Target/MBlaze/MBlazeRelocations.h new file mode 100644 index 00000000000..c298eda2195 --- /dev/null +++ b/lib/Target/MBlaze/MBlazeRelocations.h @@ -0,0 +1,47 @@ +//===- MBlazeRelocations.h - MBlaze Code Relocations ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the MBlaze target-specific relocation types. +// +//===----------------------------------------------------------------------===// + +#ifndef MBLAZERELOCATIONS_H +#define MBLAZERELOCATIONS_H + +#include "llvm/CodeGen/MachineRelocation.h" + +namespace llvm { + namespace MBlaze { + enum RelocationType { + /// reloc_pcrel_word - PC relative relocation, add the relocated value to + /// the value already in memory, after we adjust it for where the PC is. + reloc_pcrel_word = 0, + + /// reloc_picrel_word - PIC base relative relocation, add the relocated + /// value to the value already in memory, after we adjust it for where the + /// PIC base is. + reloc_picrel_word = 1, + + /// reloc_absolute_word - absolute relocation, just add the relocated + /// value to the value already in memory. + reloc_absolute_word = 2, + + /// reloc_absolute_word_sext - absolute relocation, just add the relocated + /// value to the value already in memory. In object files, it represents a + /// value which must be sign-extended when resolving the relocation. + reloc_absolute_word_sext = 3, + + /// reloc_absolute_dword - absolute relocation, just add the relocated + /// value to the value already in memory. + reloc_absolute_dword = 4 + }; + } +} + +#endif diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/lib/Target/MBlaze/MBlazeTargetMachine.cpp index 425295340d4..f5b6501a067 100644 --- a/lib/Target/MBlaze/MBlazeTargetMachine.cpp +++ b/lib/Target/MBlaze/MBlazeTargetMachine.cpp @@ -15,13 +15,51 @@ #include "MBlazeMCAsmInfo.h" #include "MBlazeTargetMachine.h" #include "llvm/PassManager.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetRegistry.h" using namespace llvm; +static MCStreamer *createMCStreamer(const Target &T, const std::string &TT, + MCContext &Ctx, TargetAsmBackend &TAB, + raw_ostream &_OS, + MCCodeEmitter *_Emitter, + bool RelaxAll) { + Triple TheTriple(TT); + switch (TheTriple.getOS()) { + case Triple::Darwin: + llvm_unreachable("MBlaze does not support Darwin MACH-O format"); + return NULL; + case Triple::MinGW32: + case Triple::MinGW64: + case Triple::Cygwin: + case Triple::Win32: + llvm_unreachable("ARM does not support Windows COFF format"); + return NULL; + default: + return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll); + } +} + + extern "C" void LLVMInitializeMBlazeTarget() { // Register the target. RegisterTargetMachine X(TheMBlazeTarget); RegisterAsmInfo A(TheMBlazeTarget); + + // Register the MC code emitter + TargetRegistry::RegisterCodeEmitter(TheMBlazeTarget, + llvm::createMBlazeMCCodeEmitter); + + // Register the asm backend + TargetRegistry::RegisterAsmBackend(TheMBlazeTarget, + createMBlazeAsmBackend); + + // Register the object streamer + TargetRegistry::RegisterObjectStreamer(TheMBlazeTarget, + createMCStreamer); + } // DataLayout --> Big-endian, 32-bit pointer/ABI/alignment @@ -39,7 +77,7 @@ MBlazeTargetMachine(const Target &T, const std::string &TT, "f64:32:32-v64:32:32-v128:32:32-n32"), InstrInfo(*this), FrameInfo(TargetFrameInfo::StackGrowsUp, 8, 0), - TLInfo(*this), TSInfo(*this) { + TLInfo(*this), TSInfo(*this), ELFWriterInfo(*this) { if (getRelocationModel() == Reloc::Default) { setRelocationModel(Reloc::Static); } diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.h b/lib/Target/MBlaze/MBlazeTargetMachine.h index 6a57e5890aa..407d0e33680 100644 --- a/lib/Target/MBlaze/MBlazeTargetMachine.h +++ b/lib/Target/MBlaze/MBlazeTargetMachine.h @@ -19,6 +19,8 @@ #include "MBlazeISelLowering.h" #include "MBlazeSelectionDAGInfo.h" #include "MBlazeIntrinsicInfo.h" +#include "MBlazeELFWriterInfo.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" @@ -34,6 +36,7 @@ namespace llvm { MBlazeTargetLowering TLInfo; MBlazeSelectionDAGInfo TSInfo; MBlazeIntrinsicInfo IntrinsicInfo; + MBlazeELFWriterInfo ELFWriterInfo; public: MBlazeTargetMachine(const Target &T, const std::string &TT, const std::string &FS); @@ -62,6 +65,10 @@ namespace llvm { const TargetIntrinsicInfo *getIntrinsicInfo() const { return &IntrinsicInfo; } + virtual const MBlazeELFWriterInfo *getELFWriterInfo() const { + return &ELFWriterInfo; + } + // Pass Pipeline Configuration virtual bool addInstSelector(PassManagerBase &PM, CodeGenOpt::Level OptLevel); diff --git a/lib/Target/MBlaze/Makefile b/lib/Target/MBlaze/Makefile index 19e508c532a..828bc62b24d 100644 --- a/lib/Target/MBlaze/Makefile +++ b/lib/Target/MBlaze/Makefile @@ -14,10 +14,11 @@ TARGET = MBlaze BUILT_SOURCES = MBlazeGenRegisterInfo.h.inc MBlazeGenRegisterNames.inc \ MBlazeGenRegisterInfo.inc MBlazeGenInstrNames.inc \ MBlazeGenInstrInfo.inc MBlazeGenAsmWriter.inc \ - MBlazeGenDAGISel.inc MBlazeGenCallingConv.inc \ + MBlazeGenDAGISel.inc \ + MBlazeGenCodeEmitter.inc MBlazeGenCallingConv.inc \ MBlazeGenSubtarget.inc MBlazeGenIntrinsics.inc -DIRS = AsmPrinter TargetInfo +DIRS = InstPrinter TargetInfo include $(LEVEL)/Makefile.common diff --git a/lib/Target/MBlaze/TODO b/lib/Target/MBlaze/TODO new file mode 100644 index 00000000000..737f111c638 --- /dev/null +++ b/lib/Target/MBlaze/TODO @@ -0,0 +1,26 @@ +* Writing out ELF files is close to working but the following needs to + be examined more closely: + - ELF files are written with the wrong E_MACHINE value because + ELFObjectWriter::WriteHeader function does not yet support + target specific E_MACHINE values. + - ELF relocation records are incorrect because the function + ELFObjectWriter::RecordRelocation is hard coded for X86/X86-64. + - Relocations use 2-byte / 4-byte to terminology in reference to + the size of the immediate value being changed. The Xilinx + terminology seems to be (???) 4-byte / 8-byte in reference + to the number of bytes of instructions that are being changed. + - BRLID and like instructions are always assumed to use a 4-byte + immediate value for the relocation and BEQID and like instructions + are always assumed to use a 2-byte immediate value for the relocation. + I think this means that conditional branches like BEQID can only + branch += 32768 bytes (~8192 instructions). We should allow conditional + branches to use 4-byte relocations but I'm not sure how to do that + right now. + +* Code generation seems to work relatively well now but the following + needs to be examined more closely: + - The stack layout needs to be examined to make sure it meets + the standard, especially in regards to var arg functions. + - The delay slot filler is ad hoc but seems to work. Load and + store instructions were prevented from being moved to delay + slots but I'm not sure that is necessary. diff --git a/lib/Target/MBlaze/TargetInfo/CMakeLists.txt b/lib/Target/MBlaze/TargetInfo/CMakeLists.txt index 5afb14d09a5..40696f63c46 100644 --- a/lib/Target/MBlaze/TargetInfo/CMakeLists.txt +++ b/lib/Target/MBlaze/TargetInfo/CMakeLists.txt @@ -1,4 +1,5 @@ -include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. ${CMAKE_CURRENT_SOURCE_DIR}/.. ) +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/.. ) add_llvm_library(LLVMMBlazeInfo MBlazeTargetInfo.cpp diff --git a/test/CodeGen/MBlaze/brind.ll b/test/CodeGen/MBlaze/brind.ll index 7798e0f56aa..4ec8605b653 100644 --- a/test/CodeGen/MBlaze/brind.ll +++ b/test/CodeGen/MBlaze/brind.ll @@ -28,32 +28,31 @@ loop: label %L3, label %L4, label %L5 ] - ; CHECK: br {{r[0-9]*}} + ; CHECK: brd {{r[0-9]*}} L1: %tmp.1 = add i32 %a, %b br label %finish - ; CHECK: br + ; CHECK: brid L2: %tmp.2 = sub i32 %a, %b br label %finish - ; CHECK: br + ; CHECK: brid L3: %tmp.3 = mul i32 %a, %b br label %finish - ; CHECK: br + ; CHECK: brid L4: %tmp.4 = sdiv i32 %a, %b br label %finish - ; CHECK: br + ; CHECK: brid L5: %tmp.5 = srem i32 %a, %b br label %finish - ; CHECK: br finish: %tmp.6 = phi i32 [ %tmp.1, %L1 ], @@ -69,5 +68,5 @@ finish: %tmp.8 = urem i32 %tmp.7, 5 br label %loop - ; CHECK: br + ; CHECK: brid } diff --git a/test/CodeGen/MBlaze/cc.ll b/test/CodeGen/MBlaze/cc.ll index aaa918ffc34..b1eb22aee9f 100644 --- a/test/CodeGen/MBlaze/cc.ll +++ b/test/CodeGen/MBlaze/cc.ll @@ -12,7 +12,7 @@ declare i32 @printf(i8*, ...) define void @params0_noret() { ; CHECK: params0_noret: ret void - ; CHECK-NOT: {{.* r3, r0, 1}} + ; CHECK-NOT: {{.* r3, .*, .*}} ; CHECK-NOT: {{.* r4, .*, .*}} ; CHECK: rtsd } @@ -20,81 +20,88 @@ define void @params0_noret() { define i8 @params0_8bitret() { ; CHECK: params0_8bitret: ret i8 1 - ; CHECK: {{.* r3, r0, 1}} + ; CHECK-NOT: {{.* r3, .*, .*}} ; CHECK-NOT: {{.* r4, .*, .*}} ; CHECK: rtsd + ; CHECK: {{.* r3, r0, 1}} } define i16 @params0_16bitret() { ; CHECK: params0_16bitret: ret i16 1 + ; CHECK: rtsd ; CHECK: {{.* r3, r0, 1}} ; CHECK-NOT: {{.* r4, .*, .*}} - ; CHECK: rtsd } define i32 @params0_32bitret() { ; CHECK: params0_32bitret: ret i32 1 - ; CHECK: {{.* r3, r0, 1}} ; CHECK-NOT: {{.* r4, .*, .*}} ; CHECK: rtsd + ; CHECK: {{.* r3, r0, 1}} } define i64 @params0_64bitret() { ; CHECK: params0_64bitret: ret i64 1 ; CHECK: {{.* r3, r0, .*}} - ; CHECK: {{.* r4, r0, 1}} ; CHECK: rtsd + ; CHECK: {{.* r4, r0, 1}} } define i32 @params1_32bitret(i32 %a) { ; CHECK: params1_32bitret: ret i32 %a - ; CHECK: {{.* r3, r5, r0}} + ; CHECK-NOT: {{.* r3, .*, .*}} ; CHECK-NOT: {{.* r4, .*, .*}} ; CHECK: rtsd + ; CHECK: {{.* r3, r5, r0}} } define i32 @params2_32bitret(i32 %a, i32 %b) { ; CHECK: params2_32bitret: ret i32 %b - ; CHECK: {{.* r3, r6, r0}} + ; CHECK-NOT: {{.* r3, .*, .*}} ; CHECK-NOT: {{.* r4, .*, .*}} ; CHECK: rtsd + ; CHECK: {{.* r3, r6, r0}} } define i32 @params3_32bitret(i32 %a, i32 %b, i32 %c) { ; CHECK: params3_32bitret: ret i32 %c - ; CHECK: {{.* r3, r7, r0}} + ; CHECK-NOT: {{.* r3, .*, .*}} ; CHECK-NOT: {{.* r4, .*, .*}} ; CHECK: rtsd + ; CHECK: {{.* r3, r7, r0}} } define i32 @params4_32bitret(i32 %a, i32 %b, i32 %c, i32 %d) { ; CHECK: params4_32bitret: ret i32 %d - ; CHECK: {{.* r3, r8, r0}} + ; CHECK-NOT: {{.* r3, .*, .*}} ; CHECK-NOT: {{.* r4, .*, .*}} ; CHECK: rtsd + ; CHECK: {{.* r3, r8, r0}} } define i32 @params5_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) { ; CHECK: params5_32bitret: ret i32 %e - ; CHECK: {{.* r3, r9, r0}} + ; CHECK-NOT: {{.* r3, .*, .*}} ; CHECK-NOT: {{.* r4, .*, .*}} ; CHECK: rtsd + ; CHECK: {{.* r3, r9, r0}} } define i32 @params6_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f) { ; CHECK: params6_32bitret: ret i32 %f - ; CHECK: {{.* r3, r10, r0}} + ; CHECK-NOT: {{.* r3, .*, .*}} ; CHECK-NOT: {{.* r4, .*, .*}} ; CHECK: rtsd + ; CHECK: {{.* r3, r10, r0}} } define i32 @params7_32bitret(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, @@ -142,53 +149,29 @@ define void @testing() { %tmp.1 = call i8 @params0_8bitret() ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i8 %tmp.1) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.2 = call i16 @params0_16bitret() ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i16 %tmp.2) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.3 = call i32 @params0_32bitret() ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.3) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.4 = call i64 @params0_64bitret() ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i64 %tmp.4) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK: {{.* r7, r4, r0}} - ; CHECK: brlid %tmp.5 = call i32 @params1_32bitret(i32 1) ; CHECK: {{.* r5, .*, .*}} ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.5) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.6 = call i32 @params2_32bitret(i32 1, i32 2) ; CHECK: {{.* r5, .*, .*}} ; CHECK: {{.* r6, .*, .*}} ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.6) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.7 = call i32 @params3_32bitret(i32 1, i32 2, i32 3) ; CHECK: {{.* r5, .*, .*}} @@ -196,10 +179,6 @@ define void @testing() { ; CHECK: {{.* r7, .*, .*}} ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.7) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.8 = call i32 @params4_32bitret(i32 1, i32 2, i32 3, i32 4) ; CHECK: {{.* r5, .*, .*}} @@ -208,10 +187,6 @@ define void @testing() { ; CHECK: {{.* r8, .*, .*}} ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.8) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.9 = call i32 @params5_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5) ; CHECK: {{.* r5, .*, .*}} @@ -221,10 +196,6 @@ define void @testing() { ; CHECK: {{.* r9, .*, .*}} ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.9) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.10 = call i32 @params6_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6) @@ -236,10 +207,6 @@ define void @testing() { ; CHECK: {{.* r10, .*, .*}} ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.10) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.11 = call i32 @params7_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7) @@ -252,10 +219,6 @@ define void @testing() { ; CHECK: {{.* r10, .*, .*}} ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.11) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.12 = call i32 @params8_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8) @@ -269,10 +232,6 @@ define void @testing() { ; CHECK: {{.* r10, .*, .*}} ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.12) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.13 = call i32 @params9_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9) @@ -287,10 +246,6 @@ define void @testing() { ; CHECK: {{.* r10, .*, .*}} ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.13) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid %tmp.14 = call i32 @params10_32bitret(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10) @@ -306,10 +261,6 @@ define void @testing() { ; CHECK: {{.* r10, .*, .*}} ; CHECK: brlid call i32 (i8*,...)* @printf(i8* %MSG.1, i32 %tmp.14) - ; CHECK: {{.* r5, .*, .*}} - ; CHECK: {{.* r6, r3, r0}} - ; CHECK-NOT: {{.* r7, .*, .*}} - ; CHECK: brlid ret void } diff --git a/test/CodeGen/MBlaze/fpu.ll b/test/CodeGen/MBlaze/fpu.ll index 83f4d831241..2aef4fd6410 100644 --- a/test/CodeGen/MBlaze/fpu.ll +++ b/test/CodeGen/MBlaze/fpu.ll @@ -10,14 +10,14 @@ define float @test_add(float %a, float %b) { ; FPU: test_add: %tmp.1 = fadd float %a, %b - ; FUN-NOT: fadd ; FUN: brlid ; FPU-NOT: brlid - ; FPU: fadd ret float %tmp.1 ; FUN: rtsd ; FPU: rtsd + ; FUN-NOT: fadd + ; FPU-NEXT: fadd } define float @test_sub(float %a, float %b) { @@ -25,14 +25,14 @@ define float @test_sub(float %a, float %b) { ; FPU: test_sub: %tmp.1 = fsub float %a, %b - ; FUN-NOT: frsub ; FUN: brlid ; FPU-NOT: brlid - ; FPU: frsub ret float %tmp.1 ; FUN: rtsd ; FPU: rtsd + ; FUN-NOT: frsub + ; FPU-NEXT: frsub } define float @test_mul(float %a, float %b) { @@ -40,14 +40,14 @@ define float @test_mul(float %a, float %b) { ; FPU: test_mul: %tmp.1 = fmul float %a, %b - ; FUN-NOT: fmul ; FUN: brlid ; FPU-NOT: brlid - ; FPU: fmul ret float %tmp.1 ; FUN: rtsd ; FPU: rtsd + ; FUN-NOT: fmul + ; FPU-NEXT: fmul } define float @test_div(float %a, float %b) { @@ -55,12 +55,12 @@ define float @test_div(float %a, float %b) { ; FPU: test_div: %tmp.1 = fdiv float %a, %b - ; FUN-NOT: fdiv ; FUN: brlid ; FPU-NOT: brlid - ; FPU: fdiv ret float %tmp.1 ; FUN: rtsd ; FPU: rtsd + ; FUN-NOT: fdiv + ; FPU-NEXT: fdiv } diff --git a/test/CodeGen/MBlaze/imm.ll b/test/CodeGen/MBlaze/imm.ll index 85fad175b77..7574687f8cd 100644 --- a/test/CodeGen/MBlaze/imm.ll +++ b/test/CodeGen/MBlaze/imm.ll @@ -7,21 +7,21 @@ define i8 @retimm_i8() { ; CHECK: retimm_i8: - ; CHECK: add - ; CHECK-NEXT: rtsd + ; CHECK: rtsd + ; CHECK-NEXT: add ; FPU: retimm_i8: - ; FPU: add - ; FPU-NEXT: rtsd + ; FPU: rtsd + ; FPU-NEXT: add ret i8 123 } define i16 @retimm_i16() { ; CHECK: retimm_i16: - ; CHECK: add - ; CHECK-NEXT: rtsd + ; CHECK: rtsd + ; CHECK-NEXT: add ; FPU: retimm_i16: - ; FPU: add - ; FPU-NEXT: rtsd + ; FPU: rtsd + ; FPU-NEXT: add ret i16 38212 } @@ -38,12 +38,12 @@ define i32 @retimm_i32() { define i64 @retimm_i64() { ; CHECK: retimm_i64: ; CHECK: add - ; CHECK-NEXT: add ; CHECK-NEXT: rtsd + ; CHECK-NEXT: add ; FPU: retimm_i64: ; FPU: add - ; FPU-NEXT: add ; FPU-NEXT: rtsd + ; FPU-NEXT: add ret i64 94581823 } @@ -53,7 +53,7 @@ define float @retimm_float() { ; CHECK-NEXT: rtsd ; FPU: retimm_float: ; FPU: or - ; FPU: rtsd + ; FPU-NEXT: rtsd ret float 12.0 } diff --git a/test/CodeGen/MBlaze/jumptable.ll b/test/CodeGen/MBlaze/jumptable.ll index 3f27c12f19a..0861810a014 100644 --- a/test/CodeGen/MBlaze/jumptable.ll +++ b/test/CodeGen/MBlaze/jumptable.ll @@ -18,8 +18,8 @@ define i32 @jmptable(i32 %arg) i32 8, label %L8 i32 9, label %L9 ] - ; CHECK: lw [[REG:r[0-9]*]] - ; CHECK: br [[REG]] + ; CHECK: lw [[REG:r[0-9]*]] + ; CHECK: brd [[REG]] L0: %var0 = add i32 %arg, 0 br label %DONE diff --git a/test/CodeGen/MBlaze/mul.ll b/test/CodeGen/MBlaze/mul.ll index 65d3e22a3e7..cefdb8d56f2 100644 --- a/test/CodeGen/MBlaze/mul.ll +++ b/test/CodeGen/MBlaze/mul.ll @@ -13,11 +13,11 @@ define i8 @test_i8(i8 %a, i8 %b) { ; FUN-NOT: mul ; FUN: brlid ; MUL-NOT: brlid - ; MUL: mul ret i8 %tmp.1 ; FUN: rtsd ; MUL: rtsd + ; MUL: mul } define i16 @test_i16(i16 %a, i16 %b) { @@ -28,11 +28,11 @@ define i16 @test_i16(i16 %a, i16 %b) { ; FUN-NOT: mul ; FUN: brlid ; MUL-NOT: brlid - ; MUL: mul ret i16 %tmp.1 ; FUN: rtsd ; MUL: rtsd + ; MUL: mul } define i32 @test_i32(i32 %a, i32 %b) { @@ -43,9 +43,9 @@ define i32 @test_i32(i32 %a, i32 %b) { ; FUN-NOT: mul ; FUN: brlid ; MUL-NOT: brlid - ; MUL: mul ret i32 %tmp.1 ; FUN: rtsd ; MUL: rtsd + ; MUL: mul } diff --git a/test/CodeGen/MBlaze/shift.ll b/test/CodeGen/MBlaze/shift.ll index 186115ec192..7eac6411dec 100644 --- a/test/CodeGen/MBlaze/shift.ll +++ b/test/CodeGen/MBlaze/shift.ll @@ -10,17 +10,17 @@ define i8 @test_i8(i8 %a, i8 %b) { ; SHT: test_i8: %tmp.1 = shl i8 %a, %b - ; FUN-NOT: bsll ; FUN: andi ; FUN: add ; FUN: bnei ; SHT-NOT: andi ; SHT-NOT: bnei - ; SHT: bsll ret i8 %tmp.1 ; FUN: rtsd ; SHT: rtsd + ; FUN-NOT: bsll + ; SHT-NEXT: bsll } define i8 @testc_i8(i8 %a, i8 %b) { @@ -28,18 +28,18 @@ define i8 @testc_i8(i8 %a, i8 %b) { ; SHT: testc_i8: %tmp.1 = shl i8 %a, 5 - ; FUN-NOT: bsll ; FUN: andi ; FUN: add ; FUN: bnei ; SHT-NOT: andi ; SHT-NOT: add ; SHT-NOT: bnei - ; SHT: bslli ret i8 %tmp.1 ; FUN: rtsd ; SHT: rtsd + ; FUN-NOT: bsll + ; SHT-NEXT: bslli } define i16 @test_i16(i16 %a, i16 %b) { @@ -47,17 +47,17 @@ define i16 @test_i16(i16 %a, i16 %b) { ; SHT: test_i16: %tmp.1 = shl i16 %a, %b - ; FUN-NOT: bsll ; FUN: andi ; FUN: add ; FUN: bnei ; SHT-NOT: andi ; SHT-NOT: bnei - ; SHT: bsll ret i16 %tmp.1 ; FUN: rtsd ; SHT: rtsd + ; FUN-NOT: bsll + ; SHT-NEXT: bsll } define i16 @testc_i16(i16 %a, i16 %b) { @@ -65,18 +65,18 @@ define i16 @testc_i16(i16 %a, i16 %b) { ; SHT: testc_i16: %tmp.1 = shl i16 %a, 5 - ; FUN-NOT: bsll ; FUN: andi ; FUN: add ; FUN: bnei ; SHT-NOT: andi ; SHT-NOT: add ; SHT-NOT: bnei - ; SHT: bslli ret i16 %tmp.1 ; FUN: rtsd ; SHT: rtsd + ; FUN-NOT: bsll + ; SHT-NEXT: bslli } define i32 @test_i32(i32 %a, i32 %b) { @@ -84,17 +84,17 @@ define i32 @test_i32(i32 %a, i32 %b) { ; SHT: test_i32: %tmp.1 = shl i32 %a, %b - ; FUN-NOT: bsll ; FUN: andi ; FUN: add ; FUN: bnei ; SHT-NOT: andi ; SHT-NOT: bnei - ; SHT: bsll ret i32 %tmp.1 ; FUN: rtsd ; SHT: rtsd + ; FUN-NOT: bsll + ; SHT-NEXT: bsll } define i32 @testc_i32(i32 %a, i32 %b) { @@ -102,16 +102,16 @@ define i32 @testc_i32(i32 %a, i32 %b) { ; SHT: testc_i32: %tmp.1 = shl i32 %a, 5 - ; FUN-NOT: bsll ; FUN: andi ; FUN: add ; FUN: bnei ; SHT-NOT: andi ; SHT-NOT: add ; SHT-NOT: bnei - ; SHT: bslli ret i32 %tmp.1 ; FUN: rtsd ; SHT: rtsd + ; FUN-NOT: bsll + ; SHT-NEXT: bslli }