diff options
author | Wesley Peck <peckw@wesleypeck.com> | 2010-10-27 00:23:01 +0000 |
---|---|---|
committer | Wesley Peck <peckw@wesleypeck.com> | 2010-10-27 00:23:01 +0000 |
commit | a06038369b830bb83742b6b39775f39dd9e69ae2 (patch) | |
tree | 3a183f442074e9a5e183229467d337ad2c06ff35 /lib | |
parent | c1d30212e911d1e55ff6b25bffefb503708883c3 (diff) | |
download | llvm-a06038369b830bb83742b6b39775f39dd9e69ae2.tar.gz llvm-a06038369b830bb83742b6b39775f39dd9e69ae2.tar.bz2 llvm-a06038369b830bb83742b6b39775f39dd9e69ae2.tar.xz |
Adding disassembler to the MicroBlaze backend.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117420 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp | 38 | ||||
-rw-r--r-- | lib/Target/MBlaze/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Target/MBlaze/Disassembler/CMakeLists.txt | 16 | ||||
-rw-r--r-- | lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp | 578 | ||||
-rw-r--r-- | lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h | 55 | ||||
-rw-r--r-- | lib/Target/MBlaze/Disassembler/Makefile | 16 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp | 3 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeInstrFSL.td | 12 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeInstrFormats.td | 29 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeInstrInfo.h | 35 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeInstrInfo.td | 155 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeMCAsmInfo.cpp | 2 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeMCAsmInfo.h | 2 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp | 46 | ||||
-rw-r--r-- | lib/Target/MBlaze/MBlazeTargetMachine.cpp | 12 | ||||
-rw-r--r-- | lib/Target/MBlaze/Makefile | 5 | ||||
-rw-r--r-- | lib/Target/MBlaze/TODO | 2 |
17 files changed, 886 insertions, 121 deletions
diff --git a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp index 399c41e8c8..d7e3047ed6 100644 --- a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp +++ b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp @@ -72,10 +72,6 @@ private: bool ParseDirectiveWord(unsigned Size, SMLoc L); - bool ParseDirectiveThumb(SMLoc L); - - bool ParseDirectiveThumbFunc(SMLoc L); - bool ParseDirectiveCode(SMLoc L); bool ParseDirectiveSyntax(SMLoc L); @@ -750,10 +746,6 @@ bool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) { StringRef IDVal = DirectiveID.getIdentifier(); if (IDVal == ".word") return ParseDirectiveWord(4, DirectiveID.getLoc()); - else if (IDVal == ".thumb") - return ParseDirectiveThumb(DirectiveID.getLoc()); - else if (IDVal == ".thumb_func") - return ParseDirectiveThumbFunc(DirectiveID.getLoc()); else if (IDVal == ".code") return ParseDirectiveCode(DirectiveID.getLoc()); else if (IDVal == ".syntax") @@ -786,36 +778,6 @@ bool MBlazeAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { return false; } -/// ParseDirectiveThumb -/// ::= .thumb -bool MBlazeAsmParser::ParseDirectiveThumb(SMLoc L) { - if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(L, "unexpected token in directive"); - Parser.Lex(); - - // TODO: set thumb mode - // TODO: tell the MC streamer the mode - // getParser().getStreamer().Emit???(); - return false; -} - -/// ParseDirectiveThumbFunc -/// ::= .thumbfunc symbol_name -bool MBlazeAsmParser::ParseDirectiveThumbFunc(SMLoc L) { - const AsmToken &Tok = Parser.getTok(); - if (Tok.isNot(AsmToken::Identifier) && Tok.isNot(AsmToken::String)) - return Error(L, "unexpected token in .syntax directive"); - Parser.Lex(); // Consume the identifier token. - - if (getLexer().isNot(AsmToken::EndOfStatement)) - return Error(L, "unexpected token in directive"); - Parser.Lex(); - - // TODO: mark symbol as a thumb symbol - // getParser().getStreamer().Emit???(); - return false; -} - /// ParseDirectiveSyntax /// ::= .syntax unified | divided bool MBlazeAsmParser::ParseDirectiveSyntax(SMLoc L) { diff --git a/lib/Target/MBlaze/CMakeLists.txt b/lib/Target/MBlaze/CMakeLists.txt index 40d3f4d4fb..8e832ee0a3 100644 --- a/lib/Target/MBlaze/CMakeLists.txt +++ b/lib/Target/MBlaze/CMakeLists.txt @@ -12,6 +12,7 @@ tablegen(MBlazeGenDAGISel.inc -gen-dag-isel) tablegen(MBlazeGenCallingConv.inc -gen-callingconv) tablegen(MBlazeGenSubtarget.inc -gen-subtarget) tablegen(MBlazeGenIntrinsics.inc -gen-tgt-intrinsic) +tablegen(MBlazeGenEDInfo.inc -gen-enhanced-disassembly-info) add_llvm_target(MBlazeCodeGen MBlazeDelaySlotFiller.cpp diff --git a/lib/Target/MBlaze/Disassembler/CMakeLists.txt b/lib/Target/MBlaze/Disassembler/CMakeLists.txt new file mode 100644 index 0000000000..9376e68a35 --- /dev/null +++ b/lib/Target/MBlaze/Disassembler/CMakeLists.txt @@ -0,0 +1,16 @@ +include_directories( ${CMAKE_CURRENT_BINARY_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/.. ) + +add_llvm_library(LLVMMBlazeDisassembler + MBlazeDisassembler.cpp + ) + +# workaround for hanging compilation on MSVC9 and 10 +if( MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 ) +set_property( + SOURCE MBlazeDisassembler.cpp + PROPERTY COMPILE_FLAGS "/Od" + ) +endif() + +add_dependencies(LLVMMBlazeDisassembler MBlazeCodeGenTable_gen) diff --git a/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp new file mode 100644 index 0000000000..01a48b2ef8 --- /dev/null +++ b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp @@ -0,0 +1,578 @@ +//===- MBlazeDisassembler.cpp - Disassembler for MicroBlaze ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is part of the MBlaze Disassembler. It contains code to translate +// the data produced by the decoder into MCInsts. +// +//===----------------------------------------------------------------------===// + +#include "MBlaze.h" +#include "MBlazeInstrInfo.h" +#include "MBlazeDisassembler.h" + +#include "llvm/MC/EDInstInfo.h" +#include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCDisassembler.h" +#include "llvm/MC/MCInst.h" +#include "llvm/Target/TargetRegistry.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/MemoryObject.h" +#include "llvm/Support/raw_ostream.h" + +// #include "MBlazeGenDecoderTables.inc" +// #include "MBlazeGenRegisterNames.inc" +#include "MBlazeGenInstrInfo.inc" +#include "MBlazeGenEDInfo.inc" + +using namespace llvm; + +const unsigned UNSUPPORTED = -1; + +static unsigned mblazeBinary2Opcode[] = { + MBlaze::ADD, MBlaze::RSUB, MBlaze::ADDC, MBlaze::RSUBC, //00,01,02,03 + MBlaze::ADDK, MBlaze::RSUBK, MBlaze::ADDKC, MBlaze::RSUBKC, //04,05,06,07 + MBlaze::ADDI, MBlaze::RSUBI, MBlaze::ADDIC, MBlaze::RSUBIC, //08,09,0A,0B + MBlaze::ADDIK, MBlaze::RSUBIK, MBlaze::ADDIKC, MBlaze::RSUBIKC, //0C,0D,0E,0F + + MBlaze::MUL, MBlaze::BSRL, MBlaze::IDIV, MBlaze::GETD, //10,11,12,13 + UNSUPPORTED, UNSUPPORTED, MBlaze::FADD, UNSUPPORTED, //14,15,16,17 + MBlaze::MULI, MBlaze::BSRLI, UNSUPPORTED, MBlaze::GET, //18,19,1A,1B + UNSUPPORTED, UNSUPPORTED, UNSUPPORTED, UNSUPPORTED, //1C,1D,1E,1F + + MBlaze::OR, MBlaze::AND, MBlaze::XOR, MBlaze::ANDN, //20,21,22,23 + MBlaze::SEXT8, MBlaze::MFS, MBlaze::BR, MBlaze::BEQ, //24,25,26,27 + MBlaze::ORI, MBlaze::ANDI, MBlaze::XORI, MBlaze::ANDNI, //28,29,2A,2B + MBlaze::IMM, MBlaze::RTSD, MBlaze::BRI, MBlaze::BEQI, //2C,2D,2E,2F + + MBlaze::LBU, MBlaze::LHU, MBlaze::LW, UNSUPPORTED, //30,31,32,33 + MBlaze::SB, MBlaze::SH, MBlaze::SW, UNSUPPORTED, //34,35,36,37 + MBlaze::LBUI, MBlaze::LHUI, MBlaze::LWI, UNSUPPORTED, //38,39,3A,3B + MBlaze::SBI, MBlaze::SHI, MBlaze::SWI, UNSUPPORTED, //3C,3D,3E,3F +}; + +static unsigned getRD( uint32_t insn ) { + return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>21)&0x1F ); +} + +static unsigned getRA( uint32_t insn ) { + return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>16)&0x1F ); +} + +static unsigned getRB( uint32_t insn ) { + return MBlazeRegisterInfo::getRegisterFromNumbering( (insn>>11)&0x1F ); +} + +static int64_t getRS( uint32_t insn ) { + int16_t val = (insn & 0x3FFF); + return val; +} + +static int64_t getIMM( uint32_t insn ) { + int16_t val = (insn & 0xFFFF); + return val; +} + +static int64_t getSHT( uint32_t insn ) { + int16_t val = (insn & 0x1F); + return val; +} + +static unsigned getFLAGS( int32_t insn ) { + return (insn & 0x7FF); +} + +static int64_t getFSL( uint32_t insn ) { + int16_t val = (insn & 0xF); + return val; +} + +static unsigned decodeMUL(uint32_t insn) { + switch (getFLAGS(insn)) { + default: return UNSUPPORTED; + case 0: return MBlaze::MUL; + case 1: return MBlaze::MULH; + case 2: return MBlaze::MULHSU; + case 3: return MBlaze::MULHU; + } +} + +static unsigned decodeSEXT(uint32_t insn) { + switch (getIMM(insn)) { + default: return UNSUPPORTED; + case 0x60: return MBlaze::SEXT8; + case 0x68: return MBlaze::WIC; + case 0x64: return MBlaze::WDC; + case 0x66: return MBlaze::WDCC; + case 0x74: return MBlaze::WDCF; + case 0x61: return MBlaze::SEXT16; + case 0x41: return MBlaze::SRL; + case 0x21: return MBlaze::SRC; + case 0x01: return MBlaze::SRA; + } +} + +static unsigned decodeBEQ(uint32_t insn) { + switch (getRD(insn)) { + default: return UNSUPPORTED; + case 0x00: return MBlaze::BEQ; + case 0x10: return MBlaze::BEQD; + case 0x05: return MBlaze::BGE; + case 0x15: return MBlaze::BGED; + case 0x04: return MBlaze::BGT; + case 0x14: return MBlaze::BGTD; + case 0x03: return MBlaze::BLE; + case 0x13: return MBlaze::BLED; + case 0x02: return MBlaze::BLT; + case 0x12: return MBlaze::BLTD; + case 0x01: return MBlaze::BNE; + case 0x11: return MBlaze::BNED; + } +} + +static unsigned decodeBEQI(uint32_t insn) { + switch (getRD(insn)) { + default: return UNSUPPORTED; + case 0x00: return MBlaze::BEQI; + case 0x10: return MBlaze::BEQID; + case 0x05: return MBlaze::BGEI; + case 0x15: return MBlaze::BGEID; + case 0x04: return MBlaze::BGTI; + case 0x14: return MBlaze::BGTID; + case 0x03: return MBlaze::BLEI; + case 0x13: return MBlaze::BLEID; + case 0x02: return MBlaze::BLTI; + case 0x12: return MBlaze::BLTID; + case 0x01: return MBlaze::BNEI; + case 0x11: return MBlaze::BNEID; + } +} + +static unsigned decodeBR(uint32_t insn) { + switch ((insn>>16)&0x1F) { + default: return UNSUPPORTED; + case 0x00: return MBlaze::BR; + case 0x08: return MBlaze::BRA; + case 0x0C: return MBlaze::BRK; + case 0x10: return MBlaze::BRD; + case 0x14: return MBlaze::BRLD; + case 0x18: return MBlaze::BRAD; + case 0x1C: return MBlaze::BRALD; + } +} + +static unsigned decodeBRI(uint32_t insn) { + switch ((insn>>16)&0x1F) { + default: return UNSUPPORTED; + case 0x00: return MBlaze::BRI; + case 0x08: return MBlaze::BRAI; + case 0x0C: return MBlaze::BRKI; + case 0x10: return MBlaze::BRID; + case 0x14: return MBlaze::BRLID; + case 0x18: return MBlaze::BRAID; + case 0x1C: return MBlaze::BRALID; + } +} + +static unsigned decodeBSRL(uint32_t insn) { + switch ((insn>>9)&0x3) { + default: return UNSUPPORTED; + case 0x2: return MBlaze::BSLL; + case 0x1: return MBlaze::BSRA; + case 0x0: return MBlaze::BSRL; + } +} + +static unsigned decodeBSRLI(uint32_t insn) { + switch ((insn>>9)&0x3) { + default: return UNSUPPORTED; + case 0x2: return MBlaze::BSLLI; + case 0x1: return MBlaze::BSRAI; + case 0x0: return MBlaze::BSRLI; + } +} + +static unsigned decodeRSUBK(uint32_t insn) { + switch (getFLAGS(insn)) { + default: return UNSUPPORTED; + case 0x0: return MBlaze::RSUBK; + case 0x1: return MBlaze::CMP; + case 0x3: return MBlaze::CMPU; + } +} + +static unsigned decodeFADD(uint32_t insn) { + switch (getFLAGS(insn)) { + default: return UNSUPPORTED; + case 0x000: return MBlaze::FADD; + case 0x080: return MBlaze::FRSUB; + case 0x100: return MBlaze::FMUL; + case 0x180: return MBlaze::FDIV; + case 0x200: return MBlaze::FCMP_UN; + case 0x210: return MBlaze::FCMP_LT; + case 0x220: return MBlaze::FCMP_EQ; + case 0x230: return MBlaze::FCMP_LE; + case 0x240: return MBlaze::FCMP_GT; + case 0x250: return MBlaze::FCMP_NE; + case 0x260: return MBlaze::FCMP_GE; + case 0x280: return MBlaze::FLT; + case 0x300: return MBlaze::FINT; + case 0x380: return MBlaze::FSQRT; + } +} + +static unsigned decodeGET(uint32_t insn) { + switch ((insn>>10)&0x3F) { + default: return UNSUPPORTED; + case 0x00: return MBlaze::GET; + case 0x01: return MBlaze::EGET; + case 0x02: return MBlaze::AGET; + case 0x03: return MBlaze::EAGET; + case 0x04: return MBlaze::TGET; + case 0x05: return MBlaze::TEGET; + case 0x06: return MBlaze::TAGET; + case 0x07: return MBlaze::TEAGET; + case 0x08: return MBlaze::CGET; + case 0x09: return MBlaze::ECGET; + case 0x0A: return MBlaze::CAGET; + case 0x0B: return MBlaze::ECAGET; + case 0x0C: return MBlaze::TCGET; + case 0x0D: return MBlaze::TECGET; + case 0x0E: return MBlaze::TCAGET; + case 0x0F: return MBlaze::TECAGET; + case 0x10: return MBlaze::NGET; + case 0x11: return MBlaze::NEGET; + case 0x12: return MBlaze::NAGET; + case 0x13: return MBlaze::NEAGET; + case 0x14: return MBlaze::TNGET; + case 0x15: return MBlaze::TNEGET; + case 0x16: return MBlaze::TNAGET; + case 0x17: return MBlaze::TNEAGET; + case 0x18: return MBlaze::NCGET; + case 0x19: return MBlaze::NECGET; + case 0x1A: return MBlaze::NCAGET; + case 0x1B: return MBlaze::NECAGET; + case 0x1C: return MBlaze::TNCGET; + case 0x1D: return MBlaze::TNECGET; + case 0x1E: return MBlaze::TNCAGET; + case 0x1F: return MBlaze::TNECAGET; + case 0x20: return MBlaze::PUT; + case 0x22: return MBlaze::APUT; + case 0x24: return MBlaze::TPUT; + case 0x26: return MBlaze::TAPUT; + case 0x28: return MBlaze::CPUT; + case 0x2A: return MBlaze::CAPUT; + case 0x2C: return MBlaze::TCPUT; + case 0x2E: return MBlaze::TCAPUT; + case 0x30: return MBlaze::NPUT; + case 0x32: return MBlaze::NAPUT; + case 0x34: return MBlaze::TNPUT; + case 0x36: return MBlaze::TNAPUT; + case 0x38: return MBlaze::NCPUT; + case 0x3A: return MBlaze::NCAPUT; + case 0x3C: return MBlaze::TNCPUT; + case 0x3E: return MBlaze::TNCAPUT; + } +} + +static unsigned decodeGETD(uint32_t insn) { + switch ((insn>>5)&0x3F) { + default: return UNSUPPORTED; + case 0x00: return MBlaze::GETD; + case 0x01: return MBlaze::EGETD; + case 0x02: return MBlaze::AGETD; + case 0x03: return MBlaze::EAGETD; + case 0x04: return MBlaze::TGETD; + case 0x05: return MBlaze::TEGETD; + case 0x06: return MBlaze::TAGETD; + case 0x07: return MBlaze::TEAGETD; + case 0x08: return MBlaze::CGETD; + case 0x09: return MBlaze::ECGETD; + case 0x0A: return MBlaze::CAGETD; + case 0x0B: return MBlaze::ECAGETD; + case 0x0C: return MBlaze::TCGETD; + case 0x0D: return MBlaze::TECGETD; + case 0x0E: return MBlaze::TCAGETD; + case 0x0F: return MBlaze::TECAGETD; + case 0x10: return MBlaze::NGETD; + case 0x11: return MBlaze::NEGETD; + case 0x12: return MBlaze::NAGETD; + case 0x13: return MBlaze::NEAGETD; + case 0x14: return MBlaze::TNGETD; + case 0x15: return MBlaze::TNEGETD; + case 0x16: return MBlaze::TNAGETD; + case 0x17: return MBlaze::TNEAGETD; + case 0x18: return MBlaze::NCGETD; + case 0x19: return MBlaze::NECGETD; + case 0x1A: return MBlaze::NCAGETD; + case 0x1B: return MBlaze::NECAGETD; + case 0x1C: return MBlaze::TNCGETD; + case 0x1D: return MBlaze::TNECGETD; + case 0x1E: return MBlaze::TNCAGETD; + case 0x1F: return MBlaze::TNECAGETD; + case 0x20: return MBlaze::PUTD; + case 0x22: return MBlaze::APUTD; + case 0x24: return MBlaze::TPUTD; + case 0x26: return MBlaze::TAPUTD; + case 0x28: return MBlaze::CPUTD; + case 0x2A: return MBlaze::CAPUTD; + case 0x2C: return MBlaze::TCPUTD; + case 0x2E: return MBlaze::TCAPUTD; + case 0x30: return MBlaze::NPUTD; + case 0x32: return MBlaze::NAPUTD; + case 0x34: return MBlaze::TNPUTD; + case 0x36: return MBlaze::TNAPUTD; + case 0x38: return MBlaze::NCPUTD; + case 0x3A: return MBlaze::NCAPUTD; + case 0x3C: return MBlaze::TNCPUTD; + case 0x3E: return MBlaze::TNCAPUTD; + } +} + +static unsigned decodeIDIV(uint32_t insn) { + switch (insn&0x3) { + default: return UNSUPPORTED; + case 0x0: return MBlaze::IDIV; + case 0x2: return MBlaze::IDIVU; + } +} + +static unsigned decodeLW(uint32_t insn) { + switch ((insn>>9)&0x3) { + default: return UNSUPPORTED; + case 0x0: return MBlaze::LW; + case 0x1: return MBlaze::LWR; + case 0x2: return MBlaze::LWX; + } +} + +static unsigned decodeSW(uint32_t insn) { + switch ((insn>>9)&0x3) { + default: return UNSUPPORTED; + case 0x0: return MBlaze::SW; + case 0x1: return MBlaze::SWR; + case 0x2: return MBlaze::SWX; + } +} + +static unsigned decodeMFS(uint32_t insn) { + switch ((insn>>15)&0x1) { + default: return UNSUPPORTED; + case 0x0: + switch ((insn>>16)&0x1F) { + default: return UNSUPPORTED; + case 0x22: return MBlaze::MSRCLR; + case 0x20: return MBlaze::MSRSET; + } + case 0x1: + switch ((insn>>14)&0x1) { + default: return UNSUPPORTED; + case 0x0: return MBlaze::MFS; + case 0x1: return MBlaze::MTS; + } + } +} + +static unsigned decodeOR(uint32_t insn) { + switch (getFLAGS(insn)) { + default: return UNSUPPORTED; + case 0x000: return MBlaze::OR; + case 0x400: return MBlaze::PCMPBF; + } +} + +static unsigned decodeXOR(uint32_t insn) { + switch (getFLAGS(insn)) { + default: return UNSUPPORTED; + case 0x000: return MBlaze::OR; + case 0x400: return MBlaze::PCMPEQ; + } +} + +static unsigned decodeANDN(uint32_t insn) { + switch (getFLAGS(insn)) { + default: return UNSUPPORTED; + case 0x000: return MBlaze::OR; + case 0x400: return MBlaze::PCMPNE; + } +} + +static unsigned decodeRTSD(uint32_t insn) { + switch ((insn>>21)&0x1F) { + default: return UNSUPPORTED; + case 0x10: return MBlaze::RTSD; + case 0x11: return MBlaze::RTID; + case 0x12: return MBlaze::RTBD; + case 0x14: return MBlaze::RTED; + } +} + +static unsigned getOPCODE( uint32_t insn ) { + unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ]; + switch (opcode) { + case MBlaze::MUL: return decodeMUL(insn); + case MBlaze::SEXT8: return decodeSEXT(insn); + case MBlaze::BEQ: return decodeBEQ(insn); + case MBlaze::BEQI: return decodeBEQI(insn); + case MBlaze::BR: return decodeBR(insn); + case MBlaze::BRI: return decodeBRI(insn); + case MBlaze::BSRL: return decodeBSRL(insn); + case MBlaze::BSRLI: return decodeBSRLI(insn); + case MBlaze::RSUBK: return decodeRSUBK(insn); + case MBlaze::FADD: return decodeFADD(insn); + case MBlaze::GET: return decodeGET(insn); + case MBlaze::GETD: return decodeGETD(insn); + case MBlaze::IDIV: return decodeIDIV(insn); + case MBlaze::LW: return decodeLW(insn); + case MBlaze::SW: return decodeSW(insn); + case MBlaze::MFS: return decodeMFS(insn); + case MBlaze::OR: return decodeOR(insn); + case MBlaze::XOR: return decodeXOR(insn); + case MBlaze::ANDN: return decodeANDN(insn); + case MBlaze::RTSD: return decodeRTSD(insn); + default: return opcode; + } +} + +EDInstInfo *MBlazeDisassembler::getEDInfo() const { + return instInfoMBlaze; +} + +// +// Public interface for the disassembler +// + +bool MBlazeDisassembler::getInstruction(MCInst &instr, + uint64_t &size, + const MemoryObject ®ion, + uint64_t address, + raw_ostream &vStream) const { + // The machine instruction. + uint32_t insn; + uint8_t bytes[4]; + + // We want to read exactly 4 bytes of data. + if (region.readBytes(address, 4, (uint8_t*)bytes, NULL) == -1) + return false; + + // Encoded as a big-endian 32-bit word in the stream. + insn = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<< 8) | (bytes[3]<<0); + + // Get the MCInst opcode from the binary instruction and make sure + // that it is a valid instruction. + unsigned opcode = getOPCODE( insn ); + if( opcode == UNSUPPORTED ) + return false; + + instr.setOpcode(opcode); + + uint64_t tsFlags = MBlazeInsts[opcode].TSFlags; + switch( (tsFlags & MBlazeII::FormMask) ) { + default: + errs() << "Opcode: " << MBlazeInsts[opcode].Name << "\n"; + errs() << "Flags: "; errs().write_hex( tsFlags ); errs() << "\n"; + return false; + + case MBlazeII::FRRR: + instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); + instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + instr.addOperand( MCOperand::CreateReg( getRB(insn) ) ); + break; + + case MBlazeII::FRRI: + instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); + instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) ); + break; + + case MBlazeII::FCRR: + instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + instr.addOperand( MCOperand::CreateReg( getRB(insn) ) ); + break; + + case MBlazeII::FCRI: + instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) ); + break; + + case MBlazeII::FRCR: + instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); + instr.addOperand( MCOperand::CreateReg( getRB(insn) ) ); + break; + + case MBlazeII::FRCI: + instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); + instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) ); + break; + + case MBlazeII::FCCR: + instr.addOperand( MCOperand::CreateReg( getRB(insn) ) ); + break; + + case MBlazeII::FCCI: + instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) ); + break; + + case MBlazeII::FRRCI: + instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); + instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + instr.addOperand( MCOperand::CreateImm( getSHT(insn) ) ); + break; + + case MBlazeII::FRRC: + instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); + instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + break; + + case MBlazeII::FRCX: + instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); + instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) ); + break; + + case MBlazeII::FRCS: + instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); + instr.addOperand( MCOperand::CreateImm( getRS(insn) ) ); + break; + + case MBlazeII::FCRCS: + instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + instr.addOperand( MCOperand::CreateImm( getRS(insn) ) ); + break; + + case MBlazeII::FCRCX: + instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) ); + break; + + case MBlazeII::FCX: + instr.addOperand( MCOperand::CreateImm( getFSL(insn) ) ); + break; + + case MBlazeII::FCR: + instr.addOperand( MCOperand::CreateReg( getRB(insn) ) ); + break; + + case MBlazeII::FRIR: + instr.addOperand( MCOperand::CreateReg( getRD(insn) ) ); + instr.addOperand( MCOperand::CreateImm( getIMM(insn) ) ); + instr.addOperand( MCOperand::CreateReg( getRA(insn) ) ); + break; + } + + return true; +} + +static MCDisassembler *createMBlazeDisassembler(const Target &T) { + return new MBlazeDisassembler; +} + +extern "C" void LLVMInitializeMBlazeDisassembler() { + // Register the disassembler. + TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget, + createMBlazeDisassembler); +} diff --git a/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h new file mode 100644 index 0000000000..d05eced0ba --- /dev/null +++ b/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h @@ -0,0 +1,55 @@ +//===- MBlazeDisassembler.h - Disassembler for MicroBlaze ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is part of the MBlaze Disassembler. It it the header for +// MBlazeDisassembler, a subclass of MCDisassembler. +// +//===----------------------------------------------------------------------===// + +#ifndef MBLAZEDISASSEMBLER_H +#define MBLAZEDISASSEMBLER_H + +#include "llvm/MC/MCDisassembler.h" + +struct InternalInstruction; + +namespace llvm { + +class MCInst; +class MemoryObject; +class raw_ostream; + +struct EDInstInfo; + +/// MBlazeDisassembler - Disassembler for all MBlaze platforms. +class MBlazeDisassembler : public MCDisassembler { +public: + /// Constructor - Initializes the disassembler. + /// + MBlazeDisassembler() : + MCDisassembler() { + } + + ~MBlazeDisassembler() { + } + + /// getInstruction - See MCDisassembler. + bool getInstruction(MCInst &instr, + uint64_t &size, + const MemoryObject ®ion, + uint64_t address, + raw_ostream &vStream) const; + + /// getEDInfo - See MCDisassembler. + EDInstInfo *getEDInfo() const; +}; + +} // namespace llvm + +#endif diff --git a/lib/Target/MBlaze/Disassembler/Makefile b/lib/Target/MBlaze/Disassembler/Makefile new file mode 100644 index 0000000000..0530b3286b --- /dev/null +++ b/lib/Target/MBlaze/Disassembler/Makefile @@ -0,0 +1,16 @@ +##===- lib/Target/MBlaze/Disassembler/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 = LLVMMBlazeDisassembler + +# Hack: we need to include 'main' MBlaze target directory to grab headers +CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/.. + +include $(LEVEL)/Makefile.common diff --git a/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp b/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp index be9de6d5a2..8918b48a5f 100644 --- a/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp +++ b/lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp @@ -7,7 +7,8 @@ // //===----------------------------------------------------------------------===// // -// Simple pass to fills delay slots with NOPs. +// A pass that attempts to fill instructions with delay slots. If no +// instructions can be moved into the delay slot then a NOP is placed there. // //===----------------------------------------------------------------------===// diff --git a/lib/Target/MBlaze/MBlazeInstrFSL.td b/lib/Target/MBlaze/MBlazeInstrFSL.td index c896be9de5..0bdd02c99f 100644 --- a/lib/Target/MBlaze/MBlazeInstrFSL.td +++ b/lib/Target/MBlaze/MBlazeInstrFSL.td @@ -11,7 +11,7 @@ // FSL Instruction Formats //===----------------------------------------------------------------------===// class FSLGet<bits<6> op, bits<5> flags, string instr_asm, Intrinsic OpNode> : - MBlazeInst<op, FFSL, (outs GPR:$dst), (ins fslimm:$b), + MBlazeInst<op, FRCX, (outs GPR:$dst), (ins fslimm:$b), !strconcat(instr_asm, " $dst, $b"), [(set GPR:$dst, (OpNode immZExt4:$b))],IIAlu> { @@ -27,7 +27,7 @@ class FSLGet<bits<6> op, bits<5> flags, string instr_asm, Intrinsic OpNode> : } class FSLGetD<bits<6> op, bits<5> flags, string instr_asm, Intrinsic OpNode> : - MBlazeInst<op, FFSLD, (outs GPR:$dst), (ins GPR:$b), + MBlazeInst<op, FRCR, (outs GPR:$dst), (ins GPR:$b), !strconcat(instr_asm, " $dst, $b"), [(set GPR:$dst, (OpNode GPR:$b))], IIAlu> { @@ -43,7 +43,7 @@ class FSLGetD<bits<6> op, bits<5> flags, string instr_asm, Intrinsic OpNode> : } class FSLPut<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> : - MBlazeInst<op, FFSL, (outs), (ins GPR:$v, fslimm:$b), + MBlazeInst<op, FCRCX, (outs), (ins GPR:$v, fslimm:$b), !strconcat(instr_asm, " $v, $b"), [(OpNode GPR:$v, immZExt4:$b)], IIAlu> { @@ -59,7 +59,7 @@ class FSLPut<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> : } class FSLPutD<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> : - MBlazeInst<op, FFSLD, (outs), (ins GPR:$v, GPR:$b), + MBlazeInst<op, FCRR, (outs), (ins GPR:$v, GPR:$b), !strconcat(instr_asm, " $v, $b"), [(OpNode GPR:$v, GPR:$b)], IIAlu> { @@ -75,7 +75,7 @@ class FSLPutD<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> : } class FSLPutT<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> : - MBlazeInst<op, FFSLT, (outs), (ins fslimm:$b), + MBlazeInst<op, FCX, (outs), (ins fslimm:$b), !strconcat(instr_asm, " $b"), [(OpNode immZExt4:$b)], IIAlu> { @@ -90,7 +90,7 @@ class FSLPutT<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> : } class FSLPutTD<bits<6> op, bits<4> flags, string instr_asm, Intrinsic OpNode> : - MBlazeInst<op, FFSLTD, (outs), (ins GPR:$b), + MBlazeInst<op, FCR, (outs), (ins GPR:$b), !strconcat(instr_asm, " $b"), [(OpNode GPR:$b)], IIAlu> { diff --git a/lib/Target/MBlaze/MBlazeInstrFormats.td b/lib/Target/MBlaze/MBlazeInstrFormats.td index 595ef1da61..71e3b12e8e 100644 --- a/lib/Target/MBlaze/MBlazeInstrFormats.td +++ b/lib/Target/MBlaze/MBlazeInstrFormats.td @@ -15,17 +15,24 @@ class Format<bits<6> 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>; +def FRRR : Format<1>; // ADD, RSUB, OR, etc. +def FRRI : Format<2>; // ADDI, RSUBI, ORI, etc. +def FCRR : Format<3>; // PUTD, WDC, WIC, BEQ, BNE, BGE, etc. +def FCRI : Format<4>; // RTID, RTED, RTSD, BEQI, BNEI, BGEI, etc. +def FRCR : Format<5>; // BRLD, BRALD, GETD +def FRCI : Format<6>; // BRLID, BRALID, MSRCLR, MSRSET +def FCCR : Format<7>; // BR, BRA, BRD, etc. +def FCCI : Format<8>; // IMM, BRI, BRAI, BRID, etc. +def FRRCI : Format<9>; // BSRLI, BSRAI, BSLLI +def FRRC : Format<10>; // SEXT8, SEXT16, SRA, SRC, SRL, FLT, FINT, FSQRT +def FRCX : Format<11>; // GET +def FRCS : Format<12>; // MFS +def FCRCS : Format<13>; // MTS +def FCRCX : Format<14>; // PUT +def FCX : Format<15>; // TPUT +def FCR : Format<16>; // TPUTD +def FRIR : Format<17>; // RSUBI +def FC : Format<18>; // NOP //===----------------------------------------------------------------------===// // Describe MBlaze instructions format diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.h b/lib/Target/MBlaze/MBlazeInstrInfo.h index eda16cc5e1..d2cc921fc0 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.h +++ b/lib/Target/MBlaze/MBlazeInstrInfo.h @@ -138,21 +138,26 @@ namespace MBlazeII { // 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 + FPseudo = 0, + FRRR, + FRRI, + FCRR, + FCRI, + FRCR, + FRCI, + FCCR, + FCCI, + FRRCI, + FRRC, + FRCX, + FRCS, + FCRCS, + FCRCX, + FCX, + FCR, + FRIR, + FC, + FormMask = 63 //===------------------------------------------------------------------===// // MBlaze Specific MachineOperand flags. diff --git a/lib/Target/MBlaze/MBlazeInstrInfo.td b/lib/Target/MBlaze/MBlazeInstrInfo.td index c10f4a8806..277fb6fc0a 100644 --- a/lib/Target/MBlaze/MBlazeInstrInfo.td +++ b/lib/Target/MBlaze/MBlazeInstrInfo.td @@ -203,6 +203,11 @@ class LogicI<bits<6> op, string instr_asm, SDNode OpNode> : [(set GPR:$dst, (OpNode GPR:$b, immZExt16:$c))], IIAlu>; +class PatCmp<bits<6> op, bits<11> flags, string instr_asm> : + TA<op, flags, (outs GPR:$dst), (ins GPR:$b, GPR:$c), + !strconcat(instr_asm, " $dst, $b, $c"), + [], IIAlu>; + //===----------------------------------------------------------------------===// // Memory Access Instructions //===----------------------------------------------------------------------===// @@ -211,6 +216,11 @@ class LoadM<bits<6> op, string instr_asm, PatFrag OpNode> : !strconcat(instr_asm, " $dst, $addr"), [(set (i32 GPR:$dst), (OpNode xaddr:$addr))], IILoad>; +class LoadW<bits<6> op, bits<11> flags, string instr_asm> : + TA<op, flags, (outs GPR:$dst), (ins memrr:$addr), + !strconcat(instr_asm, " $dst, $addr"), + [], IILoad>; + class LoadMI<bits<6> op, string instr_asm, PatFrag OpNode> : TBR<op, (outs GPR:$dst), (ins memri:$addr), !strconcat(instr_asm, " $dst, $addr"), @@ -221,6 +231,11 @@ class StoreM<bits<6> op, string instr_asm, PatFrag OpNode> : !strconcat(instr_asm, " $dst, $addr"), [(OpNode (i32 GPR:$dst), xaddr:$addr)], IIStore>; +class StoreW<bits<6> op, bits<11> flags, string instr_asm> : + TA<op, flags, (outs), (ins GPR:$dst, memrr:$addr), + !strconcat(instr_asm, " $dst, $addr"), + [], IIStore>; + class StoreMI<bits<6> op, string instr_asm, PatFrag OpNode> : TBR<op, (outs), (ins GPR:$dst, memri:$addr), !strconcat(instr_asm, " $dst, $addr"), @@ -231,10 +246,11 @@ class StoreMI<bits<6> op, string instr_asm, PatFrag OpNode> : //===----------------------------------------------------------------------===// class Branch<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> : TA<op, flags, (outs), (ins GPR:$target), - !strconcat(instr_asm, " $target"), - [], IIBranch> { + !strconcat(instr_asm, " $target"), + [], IIBranch> { let rd = 0x0; let ra = br; + let Form = FCCR; } class BranchI<bits<6> op, bits<5> br, string instr_asm> : @@ -243,25 +259,26 @@ class BranchI<bits<6> op, bits<5> br, string instr_asm> : [], IIBranch> { let rd = 0; let ra = br; + let Form = FCCI; } //===----------------------------------------------------------------------===// // Branch and Link Instructions //===----------------------------------------------------------------------===// class BranchL<bits<6> op, bits<5> br, bits<11> flags, string instr_asm> : - TA<op, flags, (outs), (ins GPR:$target), - !strconcat(instr_asm, " r15, $target"), + TA<op, flags, (outs), (ins GPR:$link, GPR:$target), + !strconcat(instr_asm, " $link, $target"), [], IIBranch> { - let rd = 15; let ra = br; + let Form = FRCR; } class BranchLI<bits<6> op, bits<5> br, string instr_asm> : - TB<op, (outs), (ins calltarget:$target), - !strconcat(instr_asm, " r15, $target"), + TB<op, (outs), (ins GPR:$link, calltarget:$target), + !strconcat(instr_asm, " $link, $target"), [], IIBranch> { - let rd = 15; let ra = br; + let Form = FRCI; } //===----------------------------------------------------------------------===// @@ -274,6 +291,7 @@ class BranchC<bits<6> op, bits<5> br, bits<11> flags, string instr_asm, !strconcat(instr_asm, " $a, $b, $offset"), [], IIBranch> { let rd = br; + let Form = FCRR; } class BranchCI<bits<6> op, bits<5> br, string instr_asm, PatFrag cond_op> : @@ -281,6 +299,7 @@ class BranchCI<bits<6> op, bits<5> br, string instr_asm, PatFrag cond_op> : !strconcat(instr_asm, " $a, $offset"), [], IIBranch> { let rd = br; + let Form = FCRI; } //===----------------------------------------------------------------------===// @@ -295,6 +314,9 @@ let isCommutable = 1, isAsCheapAsAMove = 1 in { def AND : Logic<0x21, 0x000, "and ", and>; def OR : Logic<0x20, 0x000, "or ", or>; def XOR : Logic<0x22, 0x000, "xor ", xor>; + def PCMPBF : PatCmp<0x20, 0x400, "pcmpbf ">; + def PCMPEQ : PatCmp<0x23, 0x400, "pcmpeq ">; + def PCMPNE : PatCmp<0x22, 0x400, "pcmpne ">; } let isAsCheapAsAMove = 1 in { @@ -364,7 +386,10 @@ 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 LW : LoadW<0x32, 0x0, "lw ">; + def LWR : LoadW<0x32, 0x2, "lwr ">; + def LWX : LoadW<0x32, 0x4, "lwx ">; def LBUI : LoadMI<0x38, "lbui ", zextloadi8>; def LHUI : LoadMI<0x39, "lhui ", zextloadi16>; @@ -373,7 +398,10 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in { def SB : StoreM<0x34, "sb ", truncstorei8>; def SH : StoreM<0x35, "sh ", truncstorei16>; - def SW : StoreM<0x36, "sw ", store>; + + def SW : StoreW<0x36, 0x0, "sw ">; + def SWR : StoreW<0x36, 0x2, "swr ">; + def SWX : StoreW<0x36, 0x4, "swx ">; def SBI : StoreMI<0x3C, "sbi ", truncstorei8>; def SHI : StoreMI<0x3D, "shi ", truncstorei16>; @@ -383,13 +411,12 @@ let canFoldAsLoad = 1, isReMaterializable = 1 in { // MBlaze branch instructions //===----------------------------------------------------------------------===// -let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1, - Form = FI in { +let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in { def BRI : BranchI<0x2E, 0x00, "bri ">; def BRAI : BranchI<0x2E, 0x08, "brai ">; } -let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, Form = FRI in { +let isBranch = 1, isTerminator = 1, hasCtrlDep = 1 in { def BEQI : BranchCI<0x2F, 0x00, "beqi ", seteq>; def BNEI : BranchCI<0x2F, 0x01, "bnei ", setne>; def BLTI : BranchCI<0x2F, 0x02, "blti ", setlt>; @@ -399,13 +426,12 @@ let isBranch = 1, isTerminator = 1, hasCtrlDep = 1, Form = FRI in { } let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1, - isBarrier = 1, Form = FR in { + isBarrier = 1 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 { +let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1 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>; @@ -415,13 +441,12 @@ let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, hasCtrlDep = 1, } let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1, - isBarrier = 1, Form = FI in { + isBarrier = 1 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 { +let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1 in { def BEQID : BranchCI<0x2F, 0x10, "beqid ", seteq>; def BNEID : BranchCI<0x2F, 0x11, "bneid ", setne>; def BLTID : BranchCI<0x2F, 0x12, "bltid ", setlt>; @@ -430,14 +455,14 @@ let isBranch = 1, isTerminator = 1, hasDelaySlot = 1, hasCtrlDep = 1, def BGEID : BranchCI<0x2F, 0x15, "bgeid ", setge>; } -let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, Form = FR, +let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, 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, Form = FRR in { + hasDelaySlot = 1, hasCtrlDep = 1 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>; @@ -446,7 +471,7 @@ let isBranch = 1, isIndirectBranch = 1, isTerminator = 1, def BGED : BranchC<0x27, 0x15, 0x000, "bged ", setge>; } -let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1, Form = FI, +let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1, 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 ">; @@ -454,7 +479,7 @@ let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isBarrier = 1, Form = FI, } let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isIndirectBranch = 1, - isBarrier = 1, Form = FR, + isBarrier = 1, 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 ">; @@ -462,10 +487,34 @@ let isCall = 1, hasDelaySlot = 1, hasCtrlDep = 1, isIndirectBranch = 1, } let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, - hasCtrlDep=1, rd=0x10, imm16=0x8, Form=FR in { - def RTSD : TB<0x2D, (outs), (ins GPR:$target), - "rtsd $target, 8", - [(MBlazeRet GPR:$target)], + hasCtrlDep=1, rd=0x10, Form=FCRI in { + def RTSD : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), + "rtsd $target, $imm", + [], + IIBranch>; +} + +let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, + hasCtrlDep=1, rd=0x11, Form=FCRI in { + def RTID : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), + "rtsd $target, $imm", + [], + IIBranch>; +} + +let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, + hasCtrlDep=1, rd=0x12, Form=FCRI in { + def RTBD : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), + "rtsd $target, $imm", + [], + IIBranch>; +} + +let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, + hasCtrlDep=1, rd=0x14, Form=FCRI in { + def RTED : TB<0x2D, (outs), (ins GPR:$target, simm16:$imm), + "rtsd $target, $imm", + [], IIBranch>; } @@ -474,7 +523,7 @@ let isReturn=1, isTerminator=1, hasDelaySlot=1, isBarrier=1, //===----------------------------------------------------------------------===// let neverHasSideEffects = 1 in { - def NOP : MBlazeInst< 0x20, FRRR, (outs), (ins), "nop ", [], IIAlu>; + def NOP : MBlazeInst< 0x20, FC, (outs), (ins), "nop ", [], IIAlu>; } let usesCustomInserter = 1 in { @@ -520,6 +569,38 @@ let opcode=0x08 in { } //===----------------------------------------------------------------------===// +// Misc. instructions +//===----------------------------------------------------------------------===// +def MFS : MBlazeInst<0x25, FPseudo, (outs), (ins), "mfs", [], IIAlu> { +} + +def MTS : MBlazeInst<0x25, FPseudo, (outs), (ins), "mts", [], IIAlu> { +} + +def MSRSET : MBlazeInst<0x25, FPseudo, (outs), (ins), "msrset", [], IIAlu> { +} + +def MSRCLR : MBlazeInst<0x25, FPseudo, (outs), (ins), "msrclr", [], IIAlu> { +} + +let rd=0x0, Form=FCRR in { + def WDC : TA<0x24, 0x64, (outs), (ins GPR:$a, GPR:$b), + "wdc $a, $b", [], IIAlu>; + def WDCF : TA<0x24, 0x74, (outs), (ins GPR:$a, GPR:$b), + "wdc.flush $a, $b", [], IIAlu>; + def WDCC : TA<0x24, 0x66, (outs), (ins GPR:$a, GPR:$b), + "wdc.clear $a, $b", [], IIAlu>; + def WIC : TA<0x24, 0x68, (outs), (ins GPR:$a, GPR:$b), + "wic $a, $b", [], IIAlu>; +} + +def BRK : Branch<0x26, 0x0C, 0x000, "brk ">; +def BRKI : BranchI<0x2E, 0x0C, "brki ">; + +def IMM : MBlazeInst<0x2C, FCCI, (outs), (ins simm16:$imm), + "imm $imm", [], IIAlu>; + +//===----------------------------------------------------------------------===// // Arbitrary patterns that map to one or more instructions //===----------------------------------------------------------------------===// @@ -536,9 +617,14 @@ def : Pat<(sext_inreg GPR:$src, i16), (SEXT16 GPR:$src)>; def : Pat<(sext_inreg GPR:$src, i8), (SEXT8 GPR:$src)>; // Call -def : Pat<(MBlazeJmpLink (i32 tglobaladdr:$dst)), (BRLID tglobaladdr:$dst)>; -def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)),(BRLID texternalsym:$dst)>; -def : Pat<(MBlazeJmpLink GPR:$dst), (BRLD GPR:$dst)>; +def : Pat<(MBlazeJmpLink (i32 tglobaladdr:$dst)), + (BRLID (i32 R15), tglobaladdr:$dst)>; + +def : Pat<(MBlazeJmpLink (i32 texternalsym:$dst)), + (BRLID (i32 R15), texternalsym:$dst)>; + +def : Pat<(MBlazeJmpLink GPR:$dst), + (BRLD (i32 R15), GPR:$dst)>; // Shift Instructions def : Pat<(shl GPR:$L, GPR:$R), (ShiftL GPR:$L, GPR:$R)>; @@ -613,6 +699,9 @@ def : Pat<(selectcc (i32 GPR:$L), (i32 GPR:$R), (i32 GPR:$T), (i32 GPR:$F), SETULE), (Select_CC GPR:$T, GPR:$F, (CMPU GPR:$L, GPR:$R), 6)>; +// Ret instructions +def : Pat<(MBlazeRet GPR:$target), (RTSD GPR:$target, 0x8)>; + // BR instructions def : Pat<(br bb:$T), (BRID bb:$T)>; def : Pat<(brind GPR:$T), (BRD GPR:$T)>; @@ -660,6 +749,10 @@ def : Pat<(extloadi16 iaddr:$src), (i32 (LHUI iaddr:$src))>; def : Pat<(extloadi8 xaddr:$src), (i32 (LBU xaddr:$src))>; def : Pat<(extloadi16 xaddr:$src), (i32 (LHU xaddr:$src))>; +// 32-bit load and store +def : Pat<(store (i32 GPR:$dst), xaddr:$addr), (SW GPR:$dst, xaddr:$addr)>; +def : Pat<(load xaddr:$addr), (i32 (LW xaddr:$addr))>; + // Peepholes def : Pat<(store (i32 0), iaddr:$dst), (SWI (i32 R0), iaddr:$dst)>; diff --git a/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp b/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp index 4abeb2ed5d..23b8246320 100644 --- a/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp +++ b/lib/Target/MBlaze/MBlazeMCAsmInfo.cpp @@ -14,7 +14,7 @@ #include "MBlazeMCAsmInfo.h" using namespace llvm; -MBlazeMCAsmInfo::MBlazeMCAsmInfo(const Target &T, StringRef TT) { +MBlazeMCAsmInfo::MBlazeMCAsmInfo() { AlignmentIsInBytes = false; Data16bitsDirective = "\t.half\t"; Data32bitsDirective = "\t.word\t"; diff --git a/lib/Target/MBlaze/MBlazeMCAsmInfo.h b/lib/Target/MBlaze/MBlazeMCAsmInfo.h index 9d6ff3a11e..8c3d32ba8c 100644 --- a/lib/Target/MBlaze/MBlazeMCAsmInfo.h +++ b/lib/Target/MBlaze/MBlazeMCAsmInfo.h @@ -22,7 +22,7 @@ namespace llvm { class MBlazeMCAsmInfo : public MCAsmInfo { public: - explicit MBlazeMCAsmInfo(const Target &T, StringRef TT); + explicit MBlazeMCAsmInfo(); }; } // namespace llvm diff --git a/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp b/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp index fec147decd..9672ebf5f3 100644 --- a/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp +++ b/lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp @@ -103,6 +103,8 @@ public: } void EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const; + void EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte, + raw_ostream &OS) const; void EmitImmediate(const MCInst &MI, unsigned opNo, MCFixupKind FixupKind, @@ -153,6 +155,18 @@ EmitIMM(const MCOperand &imm, unsigned &CurByte, raw_ostream &OS) const { } void MBlazeMCCodeEmitter:: +EmitIMM(const MCInst &MI, unsigned op, unsigned &CurByte, + raw_ostream &OS) const { + MCOperand mcop = MI.getOperand(op); + if (mcop.isExpr()) { + EmitByte(0x0D, CurByte, OS); + EmitByte(0x00, CurByte, OS); + EmitRawByte(0, CurByte, OS); + EmitRawByte(0, CurByte, OS); + } +} + +void MBlazeMCCodeEmitter:: EmitImmediate(const MCInst &MI, unsigned opNo, MCFixupKind FixupKind, unsigned &CurByte, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups) const { @@ -166,6 +180,8 @@ EmitImmediate(const MCInst &MI, unsigned opNo, MCFixupKind FixupKind, } } + + void MBlazeMCCodeEmitter:: EncodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups) const { @@ -177,24 +193,28 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, switch ((TSFlags & MBlazeII::FormMask)) { default: break; - case MBlazeII::Pseudo: + case MBlazeII::FPseudo: // Pseudo instructions don't get encoded. return; - case MBlazeII::RegRegImm: + case MBlazeII::FRRI: EmitImmediate( MI, 2, FK_Data_4, CurByte, OS, Fixups ); break; - case MBlazeII::RegImmReg: + case MBlazeII::FRIR: EmitImmediate( MI, 1, FK_Data_4, CurByte, OS, Fixups ); break; - case MBlazeII::RegImm: + case MBlazeII::FCRI: EmitImmediate( MI, 1, MCFixupKind(MBlaze::reloc_pcrel_2byte), CurByte, OS, Fixups ); break; - case MBlazeII::Imm: + case MBlazeII::FRCI: + EmitImmediate( MI, 1, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS, + Fixups ); + + case MBlazeII::FCCI: EmitImmediate( MI, 0, MCFixupKind(MBlaze::reloc_pcrel_4byte), CurByte, OS, Fixups ); break; @@ -207,19 +227,17 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, EmitConstant(Value, 4, CurByte, OS); break; + case MBlaze::BRLID: + case MBlaze::BRALID: + EmitIMM(MI,1,CurByte,OS); + 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); - } + EmitIMM(MI,0,CurByte,OS); EmitConstant(Value, 4, CurByte, OS); break; } diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/lib/Target/MBlaze/MBlazeTargetMachine.cpp index a340f12fa8..20e61e81c8 100644 --- a/lib/Target/MBlaze/MBlazeTargetMachine.cpp +++ b/lib/Target/MBlaze/MBlazeTargetMachine.cpp @@ -21,6 +21,14 @@ #include "llvm/Target/TargetRegistry.h" using namespace llvm; +static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) { + Triple TheTriple(TT); + switch (TheTriple.getOS()) { + default: + return new MBlazeMCAsmInfo(); + } +} + static MCStreamer *createMCStreamer(const Target &T, const std::string &TT, MCContext &Ctx, TargetAsmBackend &TAB, raw_ostream &_OS, @@ -46,7 +54,9 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT, extern "C" void LLVMInitializeMBlazeTarget() { // Register the target. RegisterTargetMachine<MBlazeTargetMachine> X(TheMBlazeTarget); - RegisterAsmInfo<MBlazeMCAsmInfo> A(TheMBlazeTarget); + + // Register the target asm info. + RegisterAsmInfoFn A(TheMBlazeTarget, createMCAsmInfo); // Register the MC code emitter TargetRegistry::RegisterCodeEmitter(TheMBlazeTarget, diff --git a/lib/Target/MBlaze/Makefile b/lib/Target/MBlaze/Makefile index ae538b4ac8..0150604084 100644 --- a/lib/Target/MBlaze/Makefile +++ b/lib/Target/MBlaze/Makefile @@ -16,9 +16,10 @@ BUILT_SOURCES = MBlazeGenRegisterInfo.h.inc MBlazeGenRegisterNames.inc \ MBlazeGenInstrInfo.inc MBlazeGenAsmWriter.inc \ MBlazeGenDAGISel.inc MBlazeGenAsmMatcher.inc \ MBlazeGenCodeEmitter.inc MBlazeGenCallingConv.inc \ - MBlazeGenSubtarget.inc MBlazeGenIntrinsics.inc + MBlazeGenSubtarget.inc MBlazeGenIntrinsics.inc \ + MBlazeGenEDInfo.inc -DIRS = InstPrinter AsmParser TargetInfo +DIRS = InstPrinter AsmParser Disassembler TargetInfo include $(LEVEL)/Makefile.common diff --git a/lib/Target/MBlaze/TODO b/lib/Target/MBlaze/TODO index 67434e94c5..95047e7c05 100644 --- a/lib/Target/MBlaze/TODO +++ b/lib/Target/MBlaze/TODO @@ -30,3 +30,5 @@ slots but I'm not sure that is necessary. - The processor itineraries are copied from a different backend and need to be updated to model the MicroBlaze correctly. + - Look at the MBlazeGenFastISel.inc stuff and make use of it + if appropriate. |