summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorWesley Peck <peckw@wesleypeck.com>2010-10-27 00:23:01 +0000
committerWesley Peck <peckw@wesleypeck.com>2010-10-27 00:23:01 +0000
commita06038369b830bb83742b6b39775f39dd9e69ae2 (patch)
tree3a183f442074e9a5e183229467d337ad2c06ff35 /lib
parentc1d30212e911d1e55ff6b25bffefb503708883c3 (diff)
downloadllvm-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.cpp38
-rw-r--r--lib/Target/MBlaze/CMakeLists.txt1
-rw-r--r--lib/Target/MBlaze/Disassembler/CMakeLists.txt16
-rw-r--r--lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp578
-rw-r--r--lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h55
-rw-r--r--lib/Target/MBlaze/Disassembler/Makefile16
-rw-r--r--lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp3
-rw-r--r--lib/Target/MBlaze/MBlazeInstrFSL.td12
-rw-r--r--lib/Target/MBlaze/MBlazeInstrFormats.td29
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.h35
-rw-r--r--lib/Target/MBlaze/MBlazeInstrInfo.td155
-rw-r--r--lib/Target/MBlaze/MBlazeMCAsmInfo.cpp2
-rw-r--r--lib/Target/MBlaze/MBlazeMCAsmInfo.h2
-rw-r--r--lib/Target/MBlaze/MBlazeMCCodeEmitter.cpp46
-rw-r--r--lib/Target/MBlaze/MBlazeTargetMachine.cpp12
-rw-r--r--lib/Target/MBlaze/Makefile5
-rw-r--r--lib/Target/MBlaze/TODO2
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 &region,
+ 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 &region,
+ 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.