llvm.org GIT mirror llvm / 6fccaaf
Remove the mblaze backend from llvm. Approval in here http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-July/064169.html git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187145 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 6 years ago
129 changed file(s) with 10 addition(s) and 14686 deletion(s). Raw diff Collapse all Expand all
7878 CppBackend
7979 Hexagon
8080 Mips
81 MBlaze
8281 MSP430
8382 NVPTX
8483 PowerPC
406406 xcore-*) llvm_cv_target_arch="XCore" ;;
407407 msp430-*) llvm_cv_target_arch="MSP430" ;;
408408 hexagon-*) llvm_cv_target_arch="Hexagon" ;;
409 mblaze-*) llvm_cv_target_arch="MBlaze" ;;
410409 nvptx-*) llvm_cv_target_arch="NVPTX" ;;
411410 s390x-*) llvm_cv_target_arch="SystemZ" ;;
412411 *) llvm_cv_target_arch="Unknown" ;;
441440 xcore-*) host_arch="XCore" ;;
442441 msp430-*) host_arch="MSP430" ;;
443442 hexagon-*) host_arch="Hexagon" ;;
444 mblaze-*) host_arch="MBlaze" ;;
445443 s390x-*) host_arch="SystemZ" ;;
446444 *) host_arch="Unknown" ;;
447445 esac
673671 XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
674672 MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
675673 Hexagon) AC_SUBST(TARGET_HAS_JIT,0) ;;
676 MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
677674 NVPTX) AC_SUBST(TARGET_HAS_JIT,0) ;;
678675 SystemZ) AC_SUBST(TARGET_HAS_JIT,1) ;;
679676 *) AC_SUBST(TARGET_HAS_JIT,0) ;;
823820 enableval=host
824821 fi
825822 case "$enableval" in
826 all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend MBlaze NVPTX Hexagon SystemZ R600" ;;
823 all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ R600" ;;
827824 *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
828825 case "$a_target" in
829826 x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
840837 msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
841838 cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
842839 hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
843 mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
844840 nvptx) TARGETS_TO_BUILD="NVPTX $TARGETS_TO_BUILD" ;;
845841 systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
846842 r600) TARGETS_TO_BUILD="R600 $TARGETS_TO_BUILD" ;;
852848 AArch64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
853849 ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
854850 Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
855 MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
856851 XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
857852 MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
858853 Hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
40324032 xcore-*) llvm_cv_target_arch="XCore" ;;
40334033 msp430-*) llvm_cv_target_arch="MSP430" ;;
40344034 hexagon-*) llvm_cv_target_arch="Hexagon" ;;
4035 mblaze-*) llvm_cv_target_arch="MBlaze" ;;
40364035 nvptx-*) llvm_cv_target_arch="NVPTX" ;;
40374036 s390x-*) llvm_cv_target_arch="SystemZ" ;;
40384037 *) llvm_cv_target_arch="Unknown" ;;
40674066 xcore-*) host_arch="XCore" ;;
40684067 msp430-*) host_arch="MSP430" ;;
40694068 hexagon-*) host_arch="Hexagon" ;;
4070 mblaze-*) host_arch="MBlaze" ;;
40714069 s390x-*) host_arch="SystemZ" ;;
40724070 *) host_arch="Unknown" ;;
40734071 esac
54245422 ;;
54255423 Hexagon) TARGET_HAS_JIT=0
54265424 ;;
5427 MBlaze) TARGET_HAS_JIT=0
5428 ;;
54295425 NVPTX) TARGET_HAS_JIT=0
54305426 ;;
54315427 SystemZ) TARGET_HAS_JIT=1
56635659 enableval=host
56645660 fi
56655661 case "$enableval" in
5666 all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend MBlaze NVPTX Hexagon SystemZ R600" ;;
5662 all) TARGETS_TO_BUILD="X86 Sparc PowerPC AArch64 ARM Mips XCore MSP430 CppBackend NVPTX Hexagon SystemZ R600" ;;
56675663 *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
56685664 case "$a_target" in
56695665 x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
56805676 msp430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
56815677 cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
56825678 hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
5683 mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
56845679 nvptx) TARGETS_TO_BUILD="NVPTX $TARGETS_TO_BUILD" ;;
56855680 systemz) TARGETS_TO_BUILD="SystemZ $TARGETS_TO_BUILD" ;;
56865681 r600) TARGETS_TO_BUILD="R600 $TARGETS_TO_BUILD" ;;
56925687 AArch64) TARGETS_TO_BUILD="AArch64 $TARGETS_TO_BUILD" ;;
56935688 ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
56945689 Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
5695 MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
56965690 XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
56975691 MSP430) TARGETS_TO_BUILD="MSP430 $TARGETS_TO_BUILD" ;;
56985692 Hexagon) TARGETS_TO_BUILD="Hexagon $TARGETS_TO_BUILD" ;;
1055010544 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
1055110545 lt_status=$lt_dlunknown
1055210546 cat > conftest.$ac_ext <
10553 #line 10554 "configure"
10547 #line 10548 "configure"
1055410548 #include "confdefs.h"
1055510549
1055610550 #if HAVE_DLFCN_H
` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` `
17871787 :raw-html:`Feature
17881788 :raw-html:`ARM
17891789 :raw-html:`Hexagon
1790 :raw-html:`MBlaze
17911790 :raw-html:`MSP430
17921791 :raw-html:`Mips
17931792 :raw-html:`NVPTX
18021801 :raw-html:`is generally reliable
18031802 :raw-html:`
18041803 :raw-html:`
1805 :raw-html:`
18061804 :raw-html:`
18071805 :raw-html:`
18081806 :raw-html:`
18171815 :raw-html:`assembly parser
18181816 :raw-html:`
18191817 :raw-html:`
1820 :raw-html:`
18211818 :raw-html:`
18221819 :raw-html:`
18231820 :raw-html:`
18321829 :raw-html:`disassembler
18331830 :raw-html:`
18341831 :raw-html:`
1835 :raw-html:`
18361832 :raw-html:`
18371833 :raw-html:`
18381834 :raw-html:`
18471843 :raw-html:`inline asm
18481844 :raw-html:`
18491845 :raw-html:`
1850 :raw-html:`
18511846 :raw-html:`
18521847 :raw-html:`
18531848 :raw-html:`
18621857 :raw-html:`jit
18631858 :raw-html:`*
18641859 :raw-html:`
1865 :raw-html:`
18661860 :raw-html:`
18671861 :raw-html:`
18681862 :raw-html:`
18771871 :raw-html:`.o file writing
18781872 :raw-html:`
18791873 :raw-html:`
1880 :raw-html:`
18811874 :raw-html:`
18821875 :raw-html:`
18831876 :raw-html:`
18921885 :raw-html:`tail calls
18931886 :raw-html:`
18941887 :raw-html:`
1895 :raw-html:`
18961888 :raw-html:`
18971889 :raw-html:`
18981890 :raw-html:`
19071899 :raw-html:`segmented stacks
19081900 :raw-html:`
19091901 :raw-html:`
1910 :raw-html:`
19111902 :raw-html:`
19121903 :raw-html:`
19131904 :raw-html:`
757757 target names that you want available in llc. The target names use all lower
758758 case. The current set of targets is:
759759
760 ``arm, cpp, hexagon, mblaze, mips, mipsel, msp430, powerpc, ptx, sparc, spu,
760 ``arm, cpp, hexagon, mips, mipsel, msp430, powerpc, ptx, sparc, spu,
761761 systemz, x86, x86_64, xcore``.
762762
763763 ``--enable-doxygen``
6363 x86, // X86: i[3-9]86
6464 x86_64, // X86-64: amd64, x86_64
6565 xcore, // XCore: xcore
66 mblaze, // MBlaze: mblaze
6766 nvptx, // NVPTX: 32-bit
6867 nvptx64, // NVPTX: 64-bit
6968 le32, // le32: generic little-endian 32-bit CPU (PNaCl / Emscripten)
9292 /// Passes all arguments in register or parameter space.
9393 PTX_Device = 72,
9494
95 /// MBLAZE_INTR - Calling convention used for MBlaze interrupt routines.
96 MBLAZE_INTR = 73,
97
98 /// MBLAZE_INTR - Calling convention used for MBlaze interrupt support
99 /// routines (i.e. GCC's save_volatiles attribute).
100 MBLAZE_SVOL = 74,
101
10295 /// SPIR_FUNC - Calling convention for SPIR non-kernel device functions.
10396 /// No lowering or expansion of arguments.
10497 /// Structures are passed as a pointer to a struct with the byval attribute.
275275 EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller
276276 EM_TILE64 = 187, // Tilera TILE64 multicore architecture family
277277 EM_TILEPRO = 188, // Tilera TILEPro multicore architecture family
278 EM_MICROBLAZE = 189, // Xilinx MicroBlaze 32-bit RISC soft processor core
279278 EM_CUDA = 190, // NVIDIA CUDA architecture
280279 EM_TILEGX = 191, // Tilera TILE-Gx multicore architecture family
281280 EM_CLOUDSHIELD = 192, // CloudShield architecture family
286285 EM_RL78 = 197, // Renesas RL78 family
287286 EM_VIDEOCORE5 = 198, // Broadcom VideoCore V processor
288287 EM_78KOR = 199, // Renesas 78KOR family
289 EM_56800EX = 200, // Freescale 56800EX Digital Signal Controller (DSC)
290 EM_MBLAZE = 47787 // Xilinx MicroBlaze
288 EM_56800EX = 200 // Freescale 56800EX Digital Signal Controller (DSC)
291289 };
292290
293291 // Object file classes.
415413 R_386_TLS_DESC = 41,
416414 R_386_IRELATIVE = 42,
417415 R_386_NUM = 43
418 };
419
420 // MBlaze relocations.
421 enum {
422 R_MICROBLAZE_NONE = 0,
423 R_MICROBLAZE_32 = 1,
424 R_MICROBLAZE_32_PCREL = 2,
425 R_MICROBLAZE_64_PCREL = 3,
426 R_MICROBLAZE_32_PCREL_LO = 4,
427 R_MICROBLAZE_64 = 5,
428 R_MICROBLAZE_32_LO = 6,
429 R_MICROBLAZE_SRO32 = 7,
430 R_MICROBLAZE_SRW32 = 8,
431 R_MICROBLAZE_64_NONE = 9,
432 R_MICROBLAZE_32_SYM_OP_SYM = 10,
433 R_MICROBLAZE_GNU_VTINHERIT = 11,
434 R_MICROBLAZE_GNU_VTENTRY = 12,
435 R_MICROBLAZE_GOTPC_64 = 13,
436 R_MICROBLAZE_GOT_64 = 14,
437 R_MICROBLAZE_PLT_64 = 15,
438 R_MICROBLAZE_REL = 16,
439 R_MICROBLAZE_JUMP_SLOT = 17,
440 R_MICROBLAZE_GLOB_DAT = 18,
441 R_MICROBLAZE_GOTOFF_64 = 19,
442 R_MICROBLAZE_GOTOFF_32 = 20,
443 R_MICROBLAZE_COPY = 21
444416 };
445417
446418 // ELF Relocation types for PPC32
175175 ECase(EM_STM8)
176176 ECase(EM_TILE64)
177177 ECase(EM_TILEPRO)
178 ECase(EM_MICROBLAZE)
179178 ECase(EM_CUDA)
180179 ECase(EM_TILEGX)
181180 ECase(EM_CLOUDSHIELD)
187186 ECase(EM_VIDEOCORE5)
188187 ECase(EM_78KOR)
189188 ECase(EM_56800EX)
190 ECase(EM_MBLAZE)
191189 #undef ECase
192190 }
193191
3737 case x86: return "i386";
3838 case x86_64: return "x86_64";
3939 case xcore: return "xcore";
40 case mblaze: return "mblaze";
4140 case nvptx: return "nvptx";
4241 case nvptx64: return "nvptx64";
4342 case le32: return "le32";
6160
6261 case ppc64:
6362 case ppc: return "ppc";
64
65 case mblaze: return "mblaze";
6663
6764 case mips:
6865 case mipsel:
170167 .Case("ppc64", ppc64)
171168 .Case("ppc32", ppc)
172169 .Case("ppc", ppc)
173 .Case("mblaze", mblaze)
174170 .Case("r600", r600)
175171 .Case("hexagon", hexagon)
176172 .Case("sparc", sparc)
200196 .Case("x86_64", "x86_64")
201197 .Case("powerpc", "ppc")
202198 .Case("powerpc64", "ppc64")
203 .Cases("mblaze", "microblaze", "mblaze")
204199 .Case("arm", "arm")
205200 .Cases("armv4t", "thumbv4t", "armv4t")
206201 .Cases("armv5", "armv5e", "thumbv5", "thumbv5e", "armv5")
224219 .Cases("amd64", "x86_64", Triple::x86_64)
225220 .Case("powerpc", Triple::ppc)
226221 .Cases("powerpc64", "ppu", Triple::ppc64)
227 .Case("mblaze", Triple::mblaze)
228222 .Case("aarch64", Triple::aarch64)
229223 .Cases("arm", "xscale", Triple::arm)
230224 // FIXME: It would be good to replace these with explicit names for all the
677671 case llvm::Triple::arm:
678672 case llvm::Triple::hexagon:
679673 case llvm::Triple::le32:
680 case llvm::Triple::mblaze:
681674 case llvm::Triple::mips:
682675 case llvm::Triple::mipsel:
683676 case llvm::Triple::nvptx:
732725 case Triple::arm:
733726 case Triple::hexagon:
734727 case Triple::le32:
735 case Triple::mblaze:
736728 case Triple::mips:
737729 case Triple::mipsel:
738730 case Triple::nvptx:
765757 case Triple::arm:
766758 case Triple::hexagon:
767759 case Triple::le32:
768 case Triple::mblaze:
769760 case Triple::msp430:
770761 case Triple::r600:
771762 case Triple::tce:
1515 ;===------------------------------------------------------------------------===;
1616
1717 [common]
18 subdirectories = AArch64 ARM CppBackend Hexagon MBlaze MSP430 NVPTX Mips PowerPC R600 Sparc SystemZ X86 XCore
18 subdirectories = AArch64 ARM CppBackend Hexagon MSP430 NVPTX Mips PowerPC R600 Sparc SystemZ X86 XCore
1919
2020 ; This is a special group whose required libraries are extended (by llvm-build)
2121 ; with the best execution engine (the native JIT, if available, or the
+0
-8
lib/Target/MBlaze/AsmParser/CMakeLists.txt less more
None include_directories( ${CMAKE_CURRENT_BINARY_DIR}/..
1 ${CMAKE_CURRENT_SOURCE_DIR}/.. )
2
3 add_llvm_library(LLVMMBlazeAsmParser
4 MBlazeAsmParser.cpp
5 )
6
7 add_dependencies(LLVMMBlazeAsmParser MBlazeCommonTableGen)
+0
-23
lib/Target/MBlaze/AsmParser/LLVMBuild.txt less more
None ;===- ./lib/Target/MBlaze/AsmParser/LLVMBuild.txt --------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Library
19 name = MBlazeAsmParser
20 parent = MBlaze
21 required_libraries = MBlazeInfo MC MCParser Support
22 add_to_library_groups = MBlaze
+0
-573
lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp less more
None //===-- MBlazeAsmParser.cpp - Parse MBlaze asm to MCInst instructions -----===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "MCTargetDesc/MBlazeBaseInfo.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/MC/MCExpr.h"
14 #include "llvm/MC/MCInst.h"
15 #include "llvm/MC/MCParser/MCAsmLexer.h"
16 #include "llvm/MC/MCParser/MCAsmParser.h"
17 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18 #include "llvm/MC/MCStreamer.h"
19 #include "llvm/MC/MCTargetAsmParser.h"
20 #include "llvm/Support/SourceMgr.h"
21 #include "llvm/Support/TargetRegistry.h"
22 #include "llvm/Support/raw_ostream.h"
23 using namespace llvm;
24
25 namespace {
26 struct MBlazeOperand;
27
28 class MBlazeAsmParser : public MCTargetAsmParser {
29 MCAsmParser &Parser;
30
31 MCAsmParser &getParser() const { return Parser; }
32 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
33
34 void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
35 bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
36
37 MBlazeOperand *ParseMemory(SmallVectorImpl &Operands);
38 MBlazeOperand *ParseRegister();
39 MBlazeOperand *ParseRegister(SMLoc &StartLoc, SMLoc &EndLoc);
40 MBlazeOperand *ParseImmediate();
41 MBlazeOperand *ParseFsl();
42 MBlazeOperand* ParseOperand(SmallVectorImpl &Operands);
43
44 virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
45
46 bool ParseDirectiveWord(unsigned Size, SMLoc L);
47
48 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
49 SmallVectorImpl &Operands,
50 MCStreamer &Out, unsigned &ErrorInfo,
51 bool MatchingInlineAsm);
52
53 /// @name Auto-generated Match Functions
54 /// {
55
56 #define GET_ASSEMBLER_HEADER
57 #include "MBlazeGenAsmMatcher.inc"
58
59 /// }
60
61 public:
62 MBlazeAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
63 : MCTargetAsmParser(), Parser(_Parser) {}
64
65 virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
66 SMLoc NameLoc,
67 SmallVectorImpl &Operands);
68
69 virtual bool ParseDirective(AsmToken DirectiveID);
70 };
71
72 /// MBlazeOperand - Instances of this class represent a parsed MBlaze machine
73 /// instruction.
74 struct MBlazeOperand : public MCParsedAsmOperand {
75 enum KindTy {
76 Token,
77 Immediate,
78 Register,
79 Memory,
80 Fsl
81 } Kind;
82
83 SMLoc StartLoc, EndLoc;
84
85 struct TokOp {
86 const char *Data;
87 unsigned Length;
88 };
89
90 struct RegOp {
91 unsigned RegNum;
92 };
93
94 struct ImmOp {
95 const MCExpr *Val;
96 };
97
98 struct MemOp {
99 unsigned Base;
100 unsigned OffReg;
101 const MCExpr *Off;
102 };
103
104 struct FslImmOp {
105 const MCExpr *Val;
106 };
107
108 union {
109 struct TokOp Tok;
110 struct RegOp Reg;
111 struct ImmOp Imm;
112 struct MemOp Mem;
113 struct FslImmOp FslImm;
114 };
115
116 MBlazeOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
117 public:
118 MBlazeOperand(const MBlazeOperand &o) : MCParsedAsmOperand() {
119 Kind = o.Kind;
120 StartLoc = o.StartLoc;
121 EndLoc = o.EndLoc;
122 switch (Kind) {
123 case Register:
124 Reg = o.Reg;
125 break;
126 case Immediate:
127 Imm = o.Imm;
128 break;
129 case Token:
130 Tok = o.Tok;
131 break;
132 case Memory:
133 Mem = o.Mem;
134 break;
135 case Fsl:
136 FslImm = o.FslImm;
137 break;
138 }
139 }
140
141 /// getStartLoc - Get the location of the first token of this operand.
142 SMLoc getStartLoc() const { return StartLoc; }
143
144 /// getEndLoc - Get the location of the last token of this operand.
145 SMLoc getEndLoc() const { return EndLoc; }
146
147 unsigned getReg() const {
148 assert(Kind == Register && "Invalid access!");
149 return Reg.RegNum;
150 }
151
152 const MCExpr *getImm() const {
153 assert(Kind == Immediate && "Invalid access!");
154 return Imm.Val;
155 }
156
157 const MCExpr *getFslImm() const {
158 assert(Kind == Fsl && "Invalid access!");
159 return FslImm.Val;
160 }
161
162 unsigned getMemBase() const {
163 assert(Kind == Memory && "Invalid access!");
164 return Mem.Base;
165 }
166
167 const MCExpr* getMemOff() const {
168 assert(Kind == Memory && "Invalid access!");
169 return Mem.Off;
170 }
171
172 unsigned getMemOffReg() const {
173 assert(Kind == Memory && "Invalid access!");
174 return Mem.OffReg;
175 }
176
177 bool isToken() const { return Kind == Token; }
178 bool isImm() const { return Kind == Immediate; }
179 bool isMem() const { return Kind == Memory; }
180 bool isFsl() const { return Kind == Fsl; }
181 bool isReg() const { return Kind == Register; }
182
183 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
184 // Add as immediates when possible. Null MCExpr = 0.
185 if (Expr == 0)
186 Inst.addOperand(MCOperand::CreateImm(0));
187 else if (const MCConstantExpr *CE = dyn_cast(Expr))
188 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
189 else
190 Inst.addOperand(MCOperand::CreateExpr(Expr));
191 }
192
193 void addRegOperands(MCInst &Inst, unsigned N) const {
194 assert(N == 1 && "Invalid number of operands!");
195 Inst.addOperand(MCOperand::CreateReg(getReg()));
196 }
197
198 void addImmOperands(MCInst &Inst, unsigned N) const {
199 assert(N == 1 && "Invalid number of operands!");
200 addExpr(Inst, getImm());
201 }
202
203 void addFslOperands(MCInst &Inst, unsigned N) const {
204 assert(N == 1 && "Invalid number of operands!");
205 addExpr(Inst, getFslImm());
206 }
207
208 void addMemOperands(MCInst &Inst, unsigned N) const {
209 assert(N == 2 && "Invalid number of operands!");
210
211 Inst.addOperand(MCOperand::CreateReg(getMemBase()));
212
213 unsigned RegOff = getMemOffReg();
214 if (RegOff)
215 Inst.addOperand(MCOperand::CreateReg(RegOff));
216 else
217 addExpr(Inst, getMemOff());
218 }
219
220 StringRef getToken() const {
221 assert(Kind == Token && "Invalid access!");
222 return StringRef(Tok.Data, Tok.Length);
223 }
224
225 virtual void print(raw_ostream &OS) const;
226
227 static MBlazeOperand *CreateToken(StringRef Str, SMLoc S) {
228 MBlazeOperand *Op = new MBlazeOperand(Token);
229 Op->Tok.Data = Str.data();
230 Op->Tok.Length = Str.size();
231 Op->StartLoc = S;
232 Op->EndLoc = S;
233 return Op;
234 }
235
236 static MBlazeOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
237 MBlazeOperand *Op = new MBlazeOperand(Register);
238 Op->Reg.RegNum = RegNum;
239 Op->StartLoc = S;
240 Op->EndLoc = E;
241 return Op;
242 }
243
244 static MBlazeOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
245 MBlazeOperand *Op = new MBlazeOperand(Immediate);
246 Op->Imm.Val = Val;
247 Op->StartLoc = S;
248 Op->EndLoc = E;
249 return Op;
250 }
251
252 static MBlazeOperand *CreateFslImm(const MCExpr *Val, SMLoc S, SMLoc E) {
253 MBlazeOperand *Op = new MBlazeOperand(Fsl);
254 Op->Imm.Val = Val;
255 Op->StartLoc = S;
256 Op->EndLoc = E;
257 return Op;
258 }
259
260 static MBlazeOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
261 SMLoc E) {
262 MBlazeOperand *Op = new MBlazeOperand(Memory);
263 Op->Mem.Base = Base;
264 Op->Mem.Off = Off;
265 Op->Mem.OffReg = 0;
266 Op->StartLoc = S;
267 Op->EndLoc = E;
268 return Op;
269 }
270
271 static MBlazeOperand *CreateMem(unsigned Base, unsigned Off, SMLoc S,
272 SMLoc E) {
273 MBlazeOperand *Op = new MBlazeOperand(Memory);
274 Op->Mem.Base = Base;
275 Op->Mem.OffReg = Off;
276 Op->Mem.Off = 0;
277 Op->StartLoc = S;
278 Op->EndLoc = E;
279 return Op;
280 }
281 };
282
283 } // end anonymous namespace.
284
285 void MBlazeOperand::print(raw_ostream &OS) const {
286 switch (Kind) {
287 case Immediate:
288 getImm()->print(OS);
289 break;
290 case Register:
291 OS << "
292 OS << getMBlazeRegisterNumbering(getReg()) << ">";
293 break;
294 case Token:
295 OS << "'" << getToken() << "'";
296 break;
297 case Memory: {
298 OS << "
299 OS << getMBlazeRegisterNumbering(getMemBase());
300 OS << ", ";
301
302 unsigned RegOff = getMemOffReg();
303 if (RegOff)
304 OS << "R" << getMBlazeRegisterNumbering(RegOff);
305 else
306 OS << getMemOff();
307 OS << ">";
308 }
309 break;
310 case Fsl:
311 getFslImm()->print(OS);
312 break;
313 }
314 }
315
316 /// @name Auto-generated Match Functions
317 /// {
318
319 static unsigned MatchRegisterName(StringRef Name);
320
321 /// }
322 //
323 bool MBlazeAsmParser::
324 MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
325 SmallVectorImpl &Operands,
326 MCStreamer &Out, unsigned &ErrorInfo,
327 bool MatchingInlineAsm) {
328 MCInst Inst;
329 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo,
330 MatchingInlineAsm)) {
331 default: break;
332 case Match_Success:
333 Out.EmitInstruction(Inst);
334 return false;
335 case Match_MissingFeature:
336 return Error(IDLoc, "instruction use requires an option to be enabled");
337 case Match_MnemonicFail:
338 return Error(IDLoc, "unrecognized instruction mnemonic");
339 case Match_InvalidOperand: {
340 SMLoc ErrorLoc = IDLoc;
341 if (ErrorInfo != ~0U) {
342 if (ErrorInfo >= Operands.size())
343 return Error(IDLoc, "too few operands for instruction");
344
345 ErrorLoc = ((MBlazeOperand*)Operands[ErrorInfo])->getStartLoc();
346 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
347 }
348
349 return Error(ErrorLoc, "invalid operand for instruction");
350 }
351 }
352
353 llvm_unreachable("Implement any new match types added!");
354 }
355
356 MBlazeOperand *MBlazeAsmParser::
357 ParseMemory(SmallVectorImpl &Operands) {
358 if (Operands.size() != 4)
359 return 0;
360
361 MBlazeOperand &Base = *(MBlazeOperand*)Operands[2];
362 MBlazeOperand &Offset = *(MBlazeOperand*)Operands[3];
363
364 SMLoc S = Base.getStartLoc();
365 SMLoc O = Offset.getStartLoc();
366 SMLoc E = Offset.getEndLoc();
367
368 if (!Base.isReg()) {
369 Error(S, "base address must be a register");
370 return 0;
371 }
372
373 if (!Offset.isReg() && !Offset.isImm()) {
374 Error(O, "offset must be a register or immediate");
375 return 0;
376 }
377
378 MBlazeOperand *Op;
379 if (Offset.isReg())
380 Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getReg(), S, E);
381 else
382 Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getImm(), S, E);
383
384 delete Operands.pop_back_val();
385 delete Operands.pop_back_val();
386 Operands.push_back(Op);
387
388 return Op;
389 }
390
391 bool MBlazeAsmParser::ParseRegister(unsigned &RegNo,
392 SMLoc &StartLoc, SMLoc &EndLoc) {
393 MBlazeOperand *Reg = ParseRegister(StartLoc, EndLoc);
394 if (!Reg)
395 return true;
396 RegNo = Reg->getReg();
397 return false;
398 }
399
400 MBlazeOperand *MBlazeAsmParser::ParseRegister() {
401 SMLoc S, E;
402 return ParseRegister(S, E);
403 }
404
405 MBlazeOperand *MBlazeAsmParser::ParseRegister(SMLoc &StartLoc, SMLoc &EndLoc) {
406 StartLoc = Parser.getTok().getLoc();
407 EndLoc = Parser.getTok().getEndLoc();
408
409 if (getLexer().getKind() != AsmToken::Identifier)
410 return 0;
411
412 unsigned RegNo = MatchRegisterName(getLexer().getTok().getIdentifier());
413 if (RegNo == 0)
414 return 0;
415
416 getLexer().Lex();
417 return MBlazeOperand::CreateReg(RegNo, StartLoc, EndLoc);
418 }
419
420 static unsigned MatchFslRegister(StringRef String) {
421 if (!String.startswith("rfsl"))
422 return -1;
423
424 unsigned regNum;
425 if (String.substr(4).getAsInteger(10,regNum))
426 return -1;
427
428 return regNum;
429 }
430
431 MBlazeOperand *MBlazeAsmParser::ParseFsl() {
432 SMLoc S = Parser.getTok().getLoc();
433 SMLoc E = Parser.getTok().getEndLoc();
434
435 switch (getLexer().getKind()) {
436 default: return 0;
437 case AsmToken::Identifier:
438 unsigned reg = MatchFslRegister(getLexer().getTok().getIdentifier());
439 if (reg >= 16)
440 return 0;
441
442 getLexer().Lex();
443 const MCExpr *EVal = MCConstantExpr::Create(reg,getContext());
444 return MBlazeOperand::CreateFslImm(EVal,S,E);
445 }
446 }
447
448 MBlazeOperand *MBlazeAsmParser::ParseImmediate() {
449 SMLoc S = Parser.getTok().getLoc();
450 SMLoc E = Parser.getTok().getEndLoc();
451
452 const MCExpr *EVal;
453 switch (getLexer().getKind()) {
454 default: return 0;
455 case AsmToken::LParen:
456 case AsmToken::Plus:
457 case AsmToken::Minus:
458 case AsmToken::Integer:
459 case AsmToken::Identifier:
460 if (getParser().parseExpression(EVal))
461 return 0;
462
463 return MBlazeOperand::CreateImm(EVal, S, E);
464 }
465 }
466
467 MBlazeOperand *MBlazeAsmParser::
468 ParseOperand(SmallVectorImpl &Operands) {
469 MBlazeOperand *Op;
470
471 // Attempt to parse the next token as a register name
472 Op = ParseRegister();
473
474 // Attempt to parse the next token as an FSL immediate
475 if (!Op)
476 Op = ParseFsl();
477
478 // Attempt to parse the next token as an immediate
479 if (!Op)
480 Op = ParseImmediate();
481
482 // If the token could not be parsed then fail
483 if (!Op) {
484 Error(Parser.getTok().getLoc(), "unknown operand");
485 return 0;
486 }
487
488 // Push the parsed operand into the list of operands
489 Operands.push_back(Op);
490 return Op;
491 }
492
493 /// Parse an mblaze instruction mnemonic followed by its operands.
494 bool MBlazeAsmParser::
495 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
496 SmallVectorImpl &Operands) {
497 // The first operands is the token for the instruction name
498 size_t dotLoc = Name.find('.');
499 Operands.push_back(MBlazeOperand::CreateToken(Name.substr(0,dotLoc),NameLoc));
500 if (dotLoc < Name.size())
501 Operands.push_back(MBlazeOperand::CreateToken(Name.substr(dotLoc),NameLoc));
502
503 // If there are no more operands then finish
504 if (getLexer().is(AsmToken::EndOfStatement))
505 return false;
506
507 // Parse the first operand
508 if (!ParseOperand(Operands))
509 return true;
510
511 while (getLexer().isNot(AsmToken::EndOfStatement) &&
512 getLexer().is(AsmToken::Comma)) {
513 // Consume the comma token
514 getLexer().Lex();
515
516 // Parse the next operand
517 if (!ParseOperand(Operands))
518 return true;
519 }
520
521 // If the instruction requires a memory operand then we need to
522 // replace the last two operands (base+offset) with a single
523 // memory operand.
524 if (Name.startswith("lw") || Name.startswith("sw") ||
525 Name.startswith("lh") || Name.startswith("sh") ||
526 Name.startswith("lb") || Name.startswith("sb"))
527 return (ParseMemory(Operands) == NULL);
528
529 return false;
530 }
531
532 /// ParseDirective parses the MBlaze specific directives
533 bool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) {
534 StringRef IDVal = DirectiveID.getIdentifier();
535 if (IDVal == ".word")
536 return ParseDirectiveWord(2, DirectiveID.getLoc());
537 return true;
538 }
539
540 /// ParseDirectiveWord
541 /// ::= .word [ expression (, expression)* ]
542 bool MBlazeAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
543 if (getLexer().isNot(AsmToken::EndOfStatement)) {
544 for (;;) {
545 const MCExpr *Value;
546 if (getParser().parseExpression(Value))
547 return true;
548
549 getParser().getStreamer().EmitValue(Value, Size);
550
551 if (getLexer().is(AsmToken::EndOfStatement))
552 break;
553
554 // FIXME: Improve diagnostic.
555 if (getLexer().isNot(AsmToken::Comma))
556 return Error(L, "unexpected token in directive");
557 Parser.Lex();
558 }
559 }
560
561 Parser.Lex();
562 return false;
563 }
564
565 /// Force static initialization.
566 extern "C" void LLVMInitializeMBlazeAsmParser() {
567 RegisterMCAsmParser X(TheMBlazeTarget);
568 }
569
570 #define GET_REGISTER_MATCHER
571 #define GET_MATCHER_IMPLEMENTATION
572 #include "MBlazeGenAsmMatcher.inc"
+0
-15
lib/Target/MBlaze/AsmParser/Makefile less more
None ##===- lib/Target/MBlaze/AsmParser/Makefile ----------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8 LEVEL = ../../../..
9 LIBRARYNAME = LLVMMBlazeAsmParser
10
11 # Hack: we need to include 'main' MBlaze target directory for private headers
12 CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
13
14 include $(LEVEL)/Makefile.common
+0
-37
lib/Target/MBlaze/CMakeLists.txt less more
None set(LLVM_TARGET_DEFINITIONS MBlaze.td)
1
2 tablegen(LLVM MBlazeGenRegisterInfo.inc -gen-register-info)
3 tablegen(LLVM MBlazeGenInstrInfo.inc -gen-instr-info)
4 tablegen(LLVM MBlazeGenCodeEmitter.inc -gen-emitter)
5 tablegen(LLVM MBlazeGenAsmWriter.inc -gen-asm-writer)
6 tablegen(LLVM MBlazeGenAsmMatcher.inc -gen-asm-matcher)
7 tablegen(LLVM MBlazeGenDAGISel.inc -gen-dag-isel)
8 tablegen(LLVM MBlazeGenCallingConv.inc -gen-callingconv)
9 tablegen(LLVM MBlazeGenSubtargetInfo.inc -gen-subtarget)
10 tablegen(LLVM MBlazeGenIntrinsics.inc -gen-tgt-intrinsic)
11 add_public_tablegen_target(MBlazeCommonTableGen)
12
13 add_llvm_target(MBlazeCodeGen
14 MBlazeDelaySlotFiller.cpp
15 MBlazeInstrInfo.cpp
16 MBlazeISelDAGToDAG.cpp
17 MBlazeISelLowering.cpp
18 MBlazeFrameLowering.cpp
19 MBlazeMachineFunction.cpp
20 MBlazeRegisterInfo.cpp
21 MBlazeSubtarget.cpp
22 MBlazeTargetMachine.cpp
23 MBlazeTargetObjectFile.cpp
24 MBlazeIntrinsicInfo.cpp
25 MBlazeSelectionDAGInfo.cpp
26 MBlazeAsmPrinter.cpp
27 MBlazeMCInstLower.cpp
28 )
29
30 add_dependencies(LLVMMBlazeCodeGen intrinsics_gen)
31
32 add_subdirectory(AsmParser)
33 add_subdirectory(Disassembler)
34 add_subdirectory(InstPrinter)
35 add_subdirectory(TargetInfo)
36 add_subdirectory(MCTargetDesc)
+0
-16
lib/Target/MBlaze/Disassembler/CMakeLists.txt less more
None include_directories( ${CMAKE_CURRENT_BINARY_DIR}/..
1 ${CMAKE_CURRENT_SOURCE_DIR}/.. )
2
3 add_llvm_library(LLVMMBlazeDisassembler
4 MBlazeDisassembler.cpp
5 )
6
7 # workaround for hanging compilation on MSVC9 and 10
8 if( MSVC_VERSION EQUAL 1500 OR MSVC_VERSION EQUAL 1600 )
9 set_property(
10 SOURCE MBlazeDisassembler.cpp
11 PROPERTY COMPILE_FLAGS "/Od"
12 )
13 endif()
14
15 add_dependencies(LLVMMBlazeDisassembler MBlazeCommonTableGen)
+0
-23
lib/Target/MBlaze/Disassembler/LLVMBuild.txt less more
None ;===- ./lib/Target/MBlaze/Disassembler/LLVMBuild.txt -----------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Library
19 name = MBlazeDisassembler
20 parent = MBlaze
21 required_libraries = MBlazeDesc MBlazeInfo MC Support
22 add_to_library_groups = MBlaze
+0
-718
lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp less more
None //===-- MBlazeDisassembler.cpp - Disassembler for MicroBlaze -------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is part of the MBlaze Disassembler. It contains code to translate
10 // the data produced by the decoder into MCInsts.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "MBlazeDisassembler.h"
15 #include "MBlaze.h"
16 #include "llvm/MC/MCDisassembler.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstrDesc.h"
19 #include "llvm/Support/Debug.h"
20 #include "llvm/Support/MemoryObject.h"
21 #include "llvm/Support/TargetRegistry.h"
22 #include "llvm/Support/raw_ostream.h"
23
24 // #include "MBlazeGenDecoderTables.inc"
25 // #include "MBlazeGenRegisterNames.inc"
26
27 namespace llvm {
28 extern const MCInstrDesc MBlazeInsts[];
29 }
30
31 using namespace llvm;
32
33 const uint16_t UNSUPPORTED = -1;
34
35 static const uint16_t mblazeBinary2Opcode[] = {
36 MBlaze::ADD, MBlaze::RSUB, MBlaze::ADDC, MBlaze::RSUBC, //00,01,02,03
37 MBlaze::ADDK, MBlaze::RSUBK, MBlaze::ADDKC, MBlaze::RSUBKC, //04,05,06,07
38 MBlaze::ADDI, MBlaze::RSUBI, MBlaze::ADDIC, MBlaze::RSUBIC, //08,09,0A,0B
39 MBlaze::ADDIK, MBlaze::RSUBIK, MBlaze::ADDIKC, MBlaze::RSUBIKC, //0C,0D,0E,0F
40
41 MBlaze::MUL, MBlaze::BSRL, MBlaze::IDIV, MBlaze::GETD, //10,11,12,13
42 UNSUPPORTED, UNSUPPORTED, MBlaze::FADD, UNSUPPORTED, //14,15,16,17
43 MBlaze::MULI, MBlaze::BSRLI, UNSUPPORTED, MBlaze::GET, //18,19,1A,1B
44 UNSUPPORTED, UNSUPPORTED, UNSUPPORTED, UNSUPPORTED, //1C,1D,1E,1F
45
46 MBlaze::OR, MBlaze::AND, MBlaze::XOR, MBlaze::ANDN, //20,21,22,23
47 MBlaze::SEXT8, MBlaze::MFS, MBlaze::BR, MBlaze::BEQ, //24,25,26,27
48 MBlaze::ORI, MBlaze::ANDI, MBlaze::XORI, MBlaze::ANDNI, //28,29,2A,2B
49 MBlaze::IMM, MBlaze::RTSD, MBlaze::BRI, MBlaze::BEQI, //2C,2D,2E,2F
50
51 MBlaze::LBU, MBlaze::LHU, MBlaze::LW, UNSUPPORTED, //30,31,32,33
52 MBlaze::SB, MBlaze::SH, MBlaze::SW, UNSUPPORTED, //34,35,36,37
53 MBlaze::LBUI, MBlaze::LHUI, MBlaze::LWI, UNSUPPORTED, //38,39,3A,3B
54 MBlaze::SBI, MBlaze::SHI, MBlaze::SWI, UNSUPPORTED, //3C,3D,3E,3F
55 };
56
57 static unsigned getRD(uint32_t insn) {
58 if (!isMBlazeRegister((insn>>21)&0x1F))
59 return UNSUPPORTED;
60 return getMBlazeRegisterFromNumbering((insn>>21)&0x1F);
61 }
62
63 static unsigned getRA(uint32_t insn) {
64 if (!getMBlazeRegisterFromNumbering((insn>>16)&0x1F))
65 return UNSUPPORTED;
66 return getMBlazeRegisterFromNumbering((insn>>16)&0x1F);
67 }
68
69 static unsigned getRB(uint32_t insn) {
70 if (!getMBlazeRegisterFromNumbering((insn>>11)&0x1F))
71 return UNSUPPORTED;
72 return getMBlazeRegisterFromNumbering((insn>>11)&0x1F);
73 }
74
75 static int64_t getRS(uint32_t insn) {
76 if (!isSpecialMBlazeRegister(insn&0x3FFF))
77 return UNSUPPORTED;
78 return getSpecialMBlazeRegisterFromNumbering(insn&0x3FFF);
79 }
80
81 static int64_t getIMM(uint32_t insn) {
82 int16_t val = (insn & 0xFFFF);
83 return val;
84 }
85
86 static int64_t getSHT(uint32_t insn) {
87 int16_t val = (insn & 0x1F);
88 return val;
89 }
90
91 static unsigned getFLAGS(int32_t insn) {
92 return (insn & 0x7FF);
93 }
94
95 static int64_t getFSL(uint32_t insn) {
96 int16_t val = (insn & 0xF);
97 return val;
98 }
99
100 static unsigned decodeMUL(uint32_t insn) {
101 switch (getFLAGS(insn)) {
102 default: return UNSUPPORTED;
103 case 0: return MBlaze::MUL;
104 case 1: return MBlaze::MULH;
105 case 2: return MBlaze::MULHSU;
106 case 3: return MBlaze::MULHU;
107 }
108 }
109
110 static unsigned decodeSEXT(uint32_t insn) {
111 switch (insn&0x7FF) {
112 default: return UNSUPPORTED;
113 case 0x60: return MBlaze::SEXT8;
114 case 0x68: return MBlaze::WIC;
115 case 0x64: return MBlaze::WDC;
116 case 0x66: return MBlaze::WDCC;
117 case 0x74: return MBlaze::WDCF;
118 case 0x61: return MBlaze::SEXT16;
119 case 0x41: return MBlaze::SRL;
120 case 0x21: return MBlaze::SRC;
121 case 0x01: return MBlaze::SRA;
122 case 0xE0: return MBlaze::CLZ;
123 }
124 }
125
126 static unsigned decodeBEQ(uint32_t insn) {
127 switch ((insn>>21)&0x1F) {
128 default: return UNSUPPORTED;
129 case 0x00: return MBlaze::BEQ;
130 case 0x10: return MBlaze::BEQD;
131 case 0x05: return MBlaze::BGE;
132 case 0x15: return MBlaze::BGED;
133 case 0x04: return MBlaze::BGT;
134 case 0x14: return MBlaze::BGTD;
135 case 0x03: return MBlaze::BLE;
136 case 0x13: return MBlaze::BLED;
137 case 0x02: return MBlaze::BLT;
138 case 0x12: return MBlaze::BLTD;
139 case 0x01: return MBlaze::BNE;
140 case 0x11: return MBlaze::BNED;
141 }
142 }
143
144 static unsigned decodeBEQI(uint32_t insn) {
145 switch ((insn>>21)&0x1F) {
146 default: return UNSUPPORTED;
147 case 0x00: return MBlaze::BEQI;
148 case 0x10: return MBlaze::BEQID;
149 case 0x05: return MBlaze::BGEI;
150 case 0x15: return MBlaze::BGEID;
151 case 0x04: return MBlaze::BGTI;
152 case 0x14: return MBlaze::BGTID;
153 case 0x03: return MBlaze::BLEI;
154 case 0x13: return MBlaze::BLEID;
155 case 0x02: return MBlaze::BLTI;
156 case 0x12: return MBlaze::BLTID;
157 case 0x01: return MBlaze::BNEI;
158 case 0x11: return MBlaze::BNEID;
159 }
160 }
161
162 static unsigned decodeBR(uint32_t insn) {
163 switch ((insn>>16)&0x1F) {
164 default: return UNSUPPORTED;
165 case 0x00: return MBlaze::BR;
166 case 0x08: return MBlaze::BRA;
167 case 0x0C: return MBlaze::BRK;
168 case 0x10: return MBlaze::BRD;
169 case 0x14: return MBlaze::BRLD;
170 case 0x18: return MBlaze::BRAD;
171 case 0x1C: return MBlaze::BRALD;
172 }
173 }
174
175 static unsigned decodeBRI(uint32_t insn) {
176 switch (insn&0x3FFFFFF) {
177 default: break;
178 case 0x0020004: return MBlaze::IDMEMBAR;
179 case 0x0220004: return MBlaze::DMEMBAR;
180 case 0x0420004: return MBlaze::IMEMBAR;
181 }
182
183 switch ((insn>>16)&0x1F) {
184 default: return UNSUPPORTED;
185 case 0x00: return MBlaze::BRI;
186 case 0x08: return MBlaze::BRAI;
187 case 0x0C: return MBlaze::BRKI;
188 case 0x10: return MBlaze::BRID;
189 case 0x14: return MBlaze::BRLID;
190 case 0x18: return MBlaze::BRAID;
191 case 0x1C: return MBlaze::BRALID;
192 }
193 }
194
195 static unsigned decodeBSRL(uint32_t insn) {
196 switch ((insn>>9)&0x3) {
197 default: return UNSUPPORTED;
198 case 0x2: return MBlaze::BSLL;
199 case 0x1: return MBlaze::BSRA;
200 case 0x0: return MBlaze::BSRL;
201 }
202 }
203
204 static unsigned decodeBSRLI(uint32_t insn) {
205 switch ((insn>>9)&0x3) {
206 default: return UNSUPPORTED;
207 case 0x2: return MBlaze::BSLLI;
208 case 0x1: return MBlaze::BSRAI;
209 case 0x0: return MBlaze::BSRLI;
210 }
211 }
212
213 static unsigned decodeRSUBK(uint32_t insn) {
214 switch (getFLAGS(insn)) {
215 default: return UNSUPPORTED;
216 case 0x0: return MBlaze::RSUBK;
217 case 0x1: return MBlaze::CMP;
218 case 0x3: return MBlaze::CMPU;
219 }
220 }
221
222 static unsigned decodeFADD(uint32_t insn) {
223 switch (getFLAGS(insn)) {
224 default: return UNSUPPORTED;
225 case 0x000: return MBlaze::FADD;
226 case 0x080: return MBlaze::FRSUB;
227 case 0x100: return MBlaze::FMUL;
228 case 0x180: return MBlaze::FDIV;
229 case 0x200: return MBlaze::FCMP_UN;
230 case 0x210: return MBlaze::FCMP_LT;
231 case 0x220: return MBlaze::FCMP_EQ;
232 case 0x230: return MBlaze::FCMP_LE;
233 case 0x240: return MBlaze::FCMP_GT;
234 case 0x250: return MBlaze::FCMP_NE;
235 case 0x260: return MBlaze::FCMP_GE;
236 case 0x280: return MBlaze::FLT;
237 case 0x300: return MBlaze::FINT;
238 case 0x380: return MBlaze::FSQRT;
239 }
240 }
241
242 static unsigned decodeGET(uint32_t insn) {
243 switch ((insn>>10)&0x3F) {
244 default: return UNSUPPORTED;
245 case 0x00: return MBlaze::GET;
246 case 0x01: return MBlaze::EGET;
247 case 0x02: return MBlaze::AGET;
248 case 0x03: return MBlaze::EAGET;
249 case 0x04: return MBlaze::TGET;
250 case 0x05: return MBlaze::TEGET;
251 case 0x06: return MBlaze::TAGET;
252 case 0x07: return MBlaze::TEAGET;
253 case 0x08: return MBlaze::CGET;
254 case 0x09: return MBlaze::ECGET;
255 case 0x0A: return MBlaze::CAGET;
256 case 0x0B: return MBlaze::ECAGET;
257 case 0x0C: return MBlaze::TCGET;
258 case 0x0D: return MBlaze::TECGET;
259 case 0x0E: return MBlaze::TCAGET;
260 case 0x0F: return MBlaze::TECAGET;
261 case 0x10: return MBlaze::NGET;
262 case 0x11: return MBlaze::NEGET;
263 case 0x12: return MBlaze::NAGET;
264 case 0x13: return MBlaze::NEAGET;
265 case 0x14: return MBlaze::TNGET;
266 case 0x15: return MBlaze::TNEGET;
267 case 0x16: return MBlaze::TNAGET;
268 case 0x17: return MBlaze::TNEAGET;
269 case 0x18: return MBlaze::NCGET;
270 case 0x19: return MBlaze::NECGET;
271 case 0x1A: return MBlaze::NCAGET;
272 case 0x1B: return MBlaze::NECAGET;
273 case 0x1C: return MBlaze::TNCGET;
274 case 0x1D: return MBlaze::TNECGET;
275 case 0x1E: return MBlaze::TNCAGET;
276 case 0x1F: return MBlaze::TNECAGET;
277 case 0x20: return MBlaze::PUT;
278 case 0x22: return MBlaze::APUT;
279 case 0x24: return MBlaze::TPUT;
280 case 0x26: return MBlaze::TAPUT;
281 case 0x28: return MBlaze::CPUT;
282 case 0x2A: return MBlaze::CAPUT;
283 case 0x2C: return MBlaze::TCPUT;
284 case 0x2E: return MBlaze::TCAPUT;
285 case 0x30: return MBlaze::NPUT;
286 case 0x32: return MBlaze::NAPUT;
287 case 0x34: return MBlaze::TNPUT;
288 case 0x36: return MBlaze::TNAPUT;
289 case 0x38: return MBlaze::NCPUT;
290 case 0x3A: return MBlaze::NCAPUT;
291 case 0x3C: return MBlaze::TNCPUT;
292 case 0x3E: return MBlaze::TNCAPUT;
293 }
294 }
295
296 static unsigned decodeGETD(uint32_t insn) {
297 switch ((insn>>5)&0x3F) {
298 default: return UNSUPPORTED;
299 case 0x00: return MBlaze::GETD;
300 case 0x01: return MBlaze::EGETD;
301 case 0x02: return MBlaze::AGETD;
302 case 0x03: return MBlaze::EAGETD;
303 case 0x04: return MBlaze::TGETD;
304 case 0x05: return MBlaze::TEGETD;
305 case 0x06: return MBlaze::TAGETD;
306 case 0x07: return MBlaze::TEAGETD;
307 case 0x08: return MBlaze::CGETD;
308 case 0x09: return MBlaze::ECGETD;
309 case 0x0A: return MBlaze::CAGETD;
310 case 0x0B: return MBlaze::ECAGETD;
311 case 0x0C: return MBlaze::TCGETD;
312 case 0x0D: return MBlaze::TECGETD;
313 case 0x0E: return MBlaze::TCAGETD;
314 case 0x0F: return MBlaze::TECAGETD;
315 case 0x10: return MBlaze::NGETD;
316 case 0x11: return MBlaze::NEGETD;
317 case 0x12: return MBlaze::NAGETD;
318 case 0x13: return MBlaze::NEAGETD;
319 case 0x14: return MBlaze::TNGETD;
320 case 0x15: return MBlaze::TNEGETD;
321 case 0x16: return MBlaze::TNAGETD;
322 case 0x17: return MBlaze::TNEAGETD;
323 case 0x18: return MBlaze::NCGETD;
324 case 0x19: return MBlaze::NECGETD;
325 case 0x1A: return MBlaze::NCAGETD;
326 case 0x1B: return MBlaze::NECAGETD;
327 case 0x1C: return MBlaze::TNCGETD;
328 case 0x1D: return MBlaze::TNECGETD;
329 case 0x1E: return MBlaze::TNCAGETD;
330 case 0x1F: return MBlaze::TNECAGETD;
331 case 0x20: return MBlaze::PUTD;
332 case 0x22: return MBlaze::APUTD;
333 case 0x24: return MBlaze::TPUTD;
334 case 0x26: return MBlaze::TAPUTD;
335 case 0x28: return MBlaze::CPUTD;
336 case 0x2A: return MBlaze::CAPUTD;
337 case 0x2C: return MBlaze::TCPUTD;
338 case 0x2E: return MBlaze::TCAPUTD;
339 case 0x30: return MBlaze::NPUTD;
340 case 0x32: return MBlaze::NAPUTD;
341 case 0x34: return MBlaze::TNPUTD;
342 case 0x36: return MBlaze::TNAPUTD;
343 case 0x38: return MBlaze::NCPUTD;
344 case 0x3A: return MBlaze::NCAPUTD;
345 case 0x3C: return MBlaze::TNCPUTD;
346 case 0x3E: return MBlaze::TNCAPUTD;
347 }
348 }
349
350 static unsigned decodeIDIV(uint32_t insn) {
351 switch (insn&0x3) {
352 default: return UNSUPPORTED;
353 case 0x0: return MBlaze::IDIV;
354 case 0x2: return MBlaze::IDIVU;
355 }
356 }
357
358 static unsigned decodeLBU(uint32_t insn) {
359 switch ((insn>>9)&0x1) {
360 default: return UNSUPPORTED;
361 case 0x0: return MBlaze::LBU;
362 case 0x1: return MBlaze::LBUR;
363 }
364 }
365
366 static unsigned decodeLHU(uint32_t insn) {
367 switch ((insn>>9)&0x1) {
368 default: return UNSUPPORTED;
369 case 0x0: return MBlaze::LHU;
370 case 0x1: return MBlaze::LHUR;
371 }
372 }
373
374 static unsigned decodeLW(uint32_t insn) {
375 switch ((insn>>9)&0x3) {
376 default: return UNSUPPORTED;
377 case 0x0: return MBlaze::LW;
378 case 0x1: return MBlaze::LWR;
379 case 0x2: return MBlaze::LWX;
380 }
381 }
382
383 static unsigned decodeSB(uint32_t insn) {
384 switch ((insn>>9)&0x1) {
385 default: return UNSUPPORTED;
386 case 0x0: return MBlaze::SB;
387 case 0x1: return MBlaze::SBR;
388 }
389 }
390
391 static unsigned decodeSH(uint32_t insn) {
392 switch ((insn>>9)&0x1) {
393 default: return UNSUPPORTED;
394 case 0x0: return MBlaze::SH;
395 case 0x1: return MBlaze::SHR;
396 }
397 }
398
399 static unsigned decodeSW(uint32_t insn) {
400 switch ((insn>>9)&0x3) {
401 default: return UNSUPPORTED;
402 case 0x0: return MBlaze::SW;
403 case 0x1: return MBlaze::SWR;
404 case 0x2: return MBlaze::SWX;
405 }
406 }
407
408 static unsigned decodeMFS(uint32_t insn) {
409 switch ((insn>>15)&0x1) {
410 default: return UNSUPPORTED;
411 case 0x0:
412 switch ((insn>>16)&0x1) {
413 default: return UNSUPPORTED;
414 case 0x0: return MBlaze::MSRSET;
415 case 0x1: return MBlaze::MSRCLR;
416 }
417 case 0x1:
418 switch ((insn>>14)&0x1) {
419 default: return UNSUPPORTED;
420 case 0x0: return MBlaze::MFS;
421 case 0x1: return MBlaze::MTS;
422 }
423 }
424 }
425
426 static unsigned decodeOR(uint32_t insn) {
427 switch (getFLAGS(insn)) {
428 default: return UNSUPPORTED;
429 case 0x000: return MBlaze::OR;
430 case 0x400: return MBlaze::PCMPBF;
431 }
432 }
433
434 static unsigned decodeXOR(uint32_t insn) {
435 switch (getFLAGS(insn)) {
436 default: return UNSUPPORTED;
437 case 0x000: return MBlaze::XOR;
438 case 0x400: return MBlaze::PCMPEQ;
439 }
440 }
441
442 static unsigned decodeANDN(uint32_t insn) {
443 switch (getFLAGS(insn)) {
444 default: return UNSUPPORTED;
445 case 0x000: return MBlaze::ANDN;
446 case 0x400: return MBlaze::PCMPNE;
447 }
448 }
449
450 static unsigned decodeRTSD(uint32_t insn) {
451 switch ((insn>>21)&0x1F) {
452 default: return UNSUPPORTED;
453 case 0x10: return MBlaze::RTSD;
454 case 0x11: return MBlaze::RTID;
455 case 0x12: return MBlaze::RTBD;
456 case 0x14: return MBlaze::RTED;
457 }
458 }
459
460 static unsigned getOPCODE(uint32_t insn) {
461 unsigned opcode = mblazeBinary2Opcode[ (insn>>26)&0x3F ];
462 switch (opcode) {
463 case MBlaze::MUL: return decodeMUL(insn);
464 case MBlaze::SEXT8: return decodeSEXT(insn);
465 case MBlaze::BEQ: return decodeBEQ(insn);
466 case MBlaze::BEQI: return decodeBEQI(insn);
467 case MBlaze::BR: return decodeBR(insn);
468 case MBlaze::BRI: return decodeBRI(insn);
469 case MBlaze::BSRL: return decodeBSRL(insn);
470 case MBlaze::BSRLI: return decodeBSRLI(insn);
471 case MBlaze::RSUBK: return decodeRSUBK(insn);
472 case MBlaze::FADD: return decodeFADD(insn);
473 case MBlaze::GET: return decodeGET(insn);
474 case MBlaze::GETD: return decodeGETD(insn);
475 case MBlaze::IDIV: return decodeIDIV(insn);
476 case MBlaze::LBU: return decodeLBU(insn);
477 case MBlaze::LHU: return decodeLHU(insn);
478 case MBlaze::LW: return decodeLW(insn);
479 case MBlaze::SB: return decodeSB(insn);
480 case MBlaze::SH: return decodeSH(insn);
481 case MBlaze::SW: return decodeSW(insn);
482 case MBlaze::MFS: return decodeMFS(insn);
483 case MBlaze::OR: return decodeOR(insn);
484 case MBlaze::XOR: return decodeXOR(insn);
485 case MBlaze::ANDN: return decodeANDN(insn);
486 case MBlaze::RTSD: return decodeRTSD(insn);
487 default: return opcode;
488 }
489 }
490
491 //
492 // Public interface for the disassembler
493 //
494
495 MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr,
496 uint64_t &size,
497 const MemoryObject ®ion,
498 uint64_t address,
499 raw_ostream &vStream,
500 raw_ostream &cStream) const {
501 // The machine instruction.
502 uint32_t insn;
503 uint8_t bytes[4];
504
505 // By default we consume 1 byte on failure
506 size = 1;
507
508 // We want to read exactly 4 bytes of data.
509 if (region.readBytes(address, 4, bytes) == -1)
510 return Fail;
511
512 // Encoded as a big-endian 32-bit word in the stream.
513 insn = (bytes[0]<<24) | (bytes[1]<<16) | (bytes[2]<< 8) | (bytes[3]<<0);
514
515 // Get the MCInst opcode from the binary instruction and make sure
516 // that it is a valid instruction.
517 unsigned opcode = getOPCODE(insn);
518 if (opcode == UNSUPPORTED)
519 return Fail;
520
521 instr.setOpcode(opcode);
522
523 unsigned RD = getRD(insn);
524 unsigned RA = getRA(insn);
525 unsigned RB = getRB(insn);
526 unsigned RS = getRS(insn);
527
528 uint64_t tsFlags = MBlazeInsts[opcode].TSFlags;
529 switch ((tsFlags & MBlazeII::FormMask)) {
530 default:
531 return Fail;
532
533 case MBlazeII::FC:
534 break;
535
536 case MBlazeII::FRRRR:
537 if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
538 return Fail;
539 instr.addOperand(MCOperand::CreateReg(RD));
540 instr.addOperand(MCOperand::CreateReg(RB));
541 instr.addOperand(MCOperand::CreateReg(RA));
542 break;
543
544 case MBlazeII::FRRR:
545 if (RD == UNSUPPORTED || RA == UNSUPPORTED || RB == UNSUPPORTED)
546 return Fail;
547 instr.addOperand(MCOperand::CreateReg(RD));
548 instr.addOperand(MCOperand::CreateReg(RA));
549 instr.addOperand(MCOperand::CreateReg(RB));
550 break;
551
552 case MBlazeII::FRR:
553 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
554 return Fail;
555 instr.addOperand(MCOperand::CreateReg(RD));
556 instr.addOperand(MCOperand::CreateReg(RA));
557 break;
558
559 case MBlazeII::FRI:
560 switch (opcode) {
561 default:
562 return Fail;
563 case MBlaze::MFS:
564 if (RD == UNSUPPORTED)
565 return Fail;
566 instr.addOperand(MCOperand::CreateReg(RD));
567 instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
568 break;
569 case MBlaze::MTS:
570 if (RA == UNSUPPORTED)
571 return Fail;
572 instr.addOperand(MCOperand::CreateImm(insn&0x3FFF));
573 instr.addOperand(MCOperand::CreateReg(RA));
574 break;
575 case MBlaze::MSRSET:
576 case MBlaze::MSRCLR:
577 if (RD == UNSUPPORTED)
578 return Fail;
579 instr.addOperand(MCOperand::CreateReg(RD));
580 instr.addOperand(MCOperand::CreateImm(insn&0x7FFF));
581 break;
582 }
583 break;
584
585 case MBlazeII::FRRI:
586 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
587 return Fail;
588 instr.addOperand(MCOperand::CreateReg(RD));
589 instr.addOperand(MCOperand::CreateReg(RA));
590 switch (opcode) {
591 default:
592 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
593 break;
594 case MBlaze::BSRLI:
595 case MBlaze::BSRAI:
596 case MBlaze::BSLLI:
597 instr.addOperand(MCOperand::CreateImm(insn&0x1F));
598 break;
599 }
600 break;
601
602 case MBlazeII::FCRR:
603 if (RA == UNSUPPORTED || RB == UNSUPPORTED)
604 return Fail;
605 instr.addOperand(MCOperand::CreateReg(RA));
606 instr.addOperand(MCOperand::CreateReg(RB));
607 break;
608
609 case MBlazeII::FCRI:
610 if (RA == UNSUPPORTED)
611 return Fail;
612 instr.addOperand(MCOperand::CreateReg(RA));
613 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
614 break;
615
616 case MBlazeII::FRCR:
617 if (RD == UNSUPPORTED || RB == UNSUPPORTED)
618 return Fail;
619 instr.addOperand(MCOperand::CreateReg(RD));
620 instr.addOperand(MCOperand::CreateReg(RB));
621 break;
622
623 case MBlazeII::FRCI:
624 if (RD == UNSUPPORTED)
625 return Fail;
626 instr.addOperand(MCOperand::CreateReg(RD));
627 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
628 break;
629
630 case MBlazeII::FCCR:
631 if (RB == UNSUPPORTED)
632 return Fail;
633 instr.addOperand(MCOperand::CreateReg(RB));
634 break;
635
636 case MBlazeII::FCCI:
637 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
638 break;
639
640 case MBlazeII::FRRCI:
641 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
642 return Fail;
643 instr.addOperand(MCOperand::CreateReg(RD));
644 instr.addOperand(MCOperand::CreateReg(RA));
645 instr.addOperand(MCOperand::CreateImm(getSHT(insn)));
646 break;
647
648 case MBlazeII::FRRC:
649 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
650 return Fail;
651 instr.addOperand(MCOperand::CreateReg(RD));
652 instr.addOperand(MCOperand::CreateReg(RA));
653 break;
654
655 case MBlazeII::FRCX:
656 if (RD == UNSUPPORTED)
657 return Fail;
658 instr.addOperand(MCOperand::CreateReg(RD));
659 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
660 break;
661
662 case MBlazeII::FRCS:
663 if (RD == UNSUPPORTED || RS == UNSUPPORTED)
664 return Fail;
665 instr.addOperand(MCOperand::CreateReg(RD));
666 instr.addOperand(MCOperand::CreateReg(RS));
667 break;
668
669 case MBlazeII::FCRCS:
670 if (RS == UNSUPPORTED || RA == UNSUPPORTED)
671 return Fail;
672 instr.addOperand(MCOperand::CreateReg(RS));
673 instr.addOperand(MCOperand::CreateReg(RA));
674 break;
675
676 case MBlazeII::FCRCX:
677 if (RA == UNSUPPORTED)
678 return Fail;
679 instr.addOperand(MCOperand::CreateReg(RA));
680 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
681 break;
682
683 case MBlazeII::FCX:
684 instr.addOperand(MCOperand::CreateImm(getFSL(insn)));
685 break;
686
687 case MBlazeII::FCR:
688 if (RB == UNSUPPORTED)
689 return Fail;
690 instr.addOperand(MCOperand::CreateReg(RB));
691 break;
692
693 case MBlazeII::FRIR:
694 if (RD == UNSUPPORTED || RA == UNSUPPORTED)
695 return Fail;
696 instr.addOperand(MCOperand::CreateReg(RD));
697 instr.addOperand(MCOperand::CreateImm(getIMM(insn)));
698 instr.addOperand(MCOperand::CreateReg(RA));
699 break;
700 }
701
702 // We always consume 4 bytes of data on success
703 size = 4;
704
705 return Success;
706 }
707
708 static MCDisassembler *createMBlazeDisassembler(const Target &T,
709 const MCSubtargetInfo &STI) {
710 return new MBlazeDisassembler(STI);
711 }
712
713 extern "C" void LLVMInitializeMBlazeDisassembler() {
714 // Register the disassembler.
715 TargetRegistry::RegisterMCDisassembler(TheMBlazeTarget,
716 createMBlazeDisassembler);
717 }
+0
-49
lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h less more
None //===-- MBlazeDisassembler.h - Disassembler for MicroBlaze -----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is part of the MBlaze Disassembler. It it the header for
10 // MBlazeDisassembler, a subclass of MCDisassembler.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef MBLAZEDISASSEMBLER_H
15 #define MBLAZEDISASSEMBLER_H
16
17 #include "llvm/MC/MCDisassembler.h"
18
19 namespace llvm {
20
21 class MCInst;
22 class MemoryObject;
23 class raw_ostream;
24
25 /// MBlazeDisassembler - Disassembler for all MBlaze platforms.
26 class MBlazeDisassembler : public MCDisassembler {
27 public:
28 /// Constructor - Initializes the disassembler.
29 ///
30 MBlazeDisassembler(const MCSubtargetInfo &STI) :
31 MCDisassembler(STI) {
32 }
33
34 ~MBlazeDisassembler() {
35 }
36
37 /// getInstruction - See MCDisassembler.
38 MCDisassembler::DecodeStatus getInstruction(MCInst &instr,
39 uint64_t &size,
40 const MemoryObject ®ion,
41 uint64_t address,
42 raw_ostream &vStream,
43 raw_ostream &cStream) const;
44 };
45
46 } // namespace llvm
47
48 #endif
+0
-16
lib/Target/MBlaze/Disassembler/Makefile less more
None ##===- lib/Target/MBlaze/Disassembler/Makefile -------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8
9 LEVEL = ../../../..
10 LIBRARYNAME = LLVMMBlazeDisassembler
11
12 # Hack: we need to include 'main' MBlaze target directory to grab headers
13 CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
14
15 include $(LEVEL)/Makefile.common
+0
-8
lib/Target/MBlaze/InstPrinter/CMakeLists.txt less more
None include_directories( ${CMAKE_CURRENT_BINARY_DIR}/..
1 ${CMAKE_CURRENT_SOURCE_DIR}/.. )
2
3 add_llvm_library(LLVMMBlazeAsmPrinter
4 MBlazeInstPrinter.cpp
5 )
6
7 add_dependencies(LLVMMBlazeAsmPrinter MBlazeCommonTableGen)
+0
-23
lib/Target/MBlaze/InstPrinter/LLVMBuild.txt less more
None ;===- ./lib/Target/MBlaze/InstPrinter/LLVMBuild.txt ------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [component_0]
18 type = Library
19 name = MBlazeAsmPrinter
20 parent = MBlaze
21 required_libraries = MC Support
22 add_to_library_groups = MBlaze
+0
-71
lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.cpp less more
None //===-- MBlazeInstPrinter.cpp - Convert MBlaze MCInst to assembly syntax --===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class prints an MBlaze MCInst to a .s file.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #define DEBUG_TYPE "asm-printer"
14 #include "MBlazeInstPrinter.h"
15 #include "MBlaze.h"
16 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/FormattedStream.h"
21 using namespace llvm;
22
23
24 // Include the auto-generated portion of the assembly writer.
25 #include "MBlazeGenAsmWriter.inc"
26
27 void MBlazeInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
28 StringRef Annot) {
29 printInstruction(MI, O);
30 printAnnotation(O, Annot);
31 }
32
33 void MBlazeInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
34 raw_ostream &O, const char *Modifier) {
35 assert((Modifier == 0 || Modifier[0] == 0) && "No modifiers supported");
36 const MCOperand &Op = MI->getOperand(OpNo);
37 if (Op.isReg()) {
38 O << getRegisterName(Op.getReg());
39 } else if (Op.isImm()) {
40 O << (int32_t)Op.getImm();
41 } else {
42 assert(Op.isExpr() && "unknown operand kind in printOperand");
43 O << *Op.getExpr();
44 }
45 }
46
47 void MBlazeInstPrinter::printFSLImm(const MCInst *MI, int OpNo,
48 raw_ostream &O) {
49 const MCOperand &MO = MI->getOperand(OpNo);
50 if (MO.isImm())
51 O << "rfsl" << MO.getImm();
52 else
53 printOperand(MI, OpNo, O, NULL);
54 }
55
56 void MBlazeInstPrinter::printUnsignedImm(const MCInst *MI, int OpNo,
57 raw_ostream &O) {
58 const MCOperand &MO = MI->getOperand(OpNo);
59 if (MO.isImm())
60 O << (uint32_t)MO.getImm();
61 else
62 printOperand(MI, OpNo, O, NULL);
63 }
64
65 void MBlazeInstPrinter::printMemOperand(const MCInst *MI, int OpNo,
66 raw_ostream &O, const char *Modifier) {
67 printOperand(MI, OpNo, O, NULL);
68 O << ", ";
69 printOperand(MI, OpNo+1, O, NULL);
70 }
+0
-43
lib/Target/MBlaze/InstPrinter/MBlazeInstPrinter.h less more
None //= MBlazeInstPrinter.h - Convert MBlaze MCInst to assembly syntax -*- C++ -*-//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class prints a MBlaze MCInst to a .s file.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef MBLAZEINSTPRINTER_H
14 #define MBLAZEINSTPRINTER_H
15
16 #include "llvm/MC/MCInstPrinter.h"
17
18 namespace llvm {
19 class MCOperand;
20
21 class MBlazeInstPrinter : public MCInstPrinter {
22 public:
23 MBlazeInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
24 const MCRegisterInfo &MRI)
25 : MCInstPrinter(MAI, MII, MRI) {}
26
27 virtual void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot);
28
29 // Autogenerated by tblgen.
30 void printInstruction(const MCInst *MI, raw_ostream &O);
31 static const char *getRegisterName(unsigned RegNo);
32
33 void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
34 const char *Modifier = 0);
35 void printFSLImm(const MCInst *MI, int OpNo, raw_ostream &O);
36 void printUnsignedImm(const MCInst *MI, int OpNo, raw_ostream &O);
37 void printMemOperand(const MCInst *MI, int OpNo,raw_ostream &O,
38 const char *Modifier = 0);
39 };
40 }
41
42 #endif
+0
-16
lib/Target/MBlaze/InstPrinter/Makefile less more
None ##===- lib/Target/MBlaze/AsmPrinter/Makefile ---------------*- Makefile -*-===##
1 #
2 # The LLVM Compiler Infrastructure
3 #
4 # This file is distributed under the University of Illinois Open Source
5 # License. See LICENSE.TXT for details.
6 #
7 ##===----------------------------------------------------------------------===##
8 LEVEL = ../../../..
9 LIBRARYNAME = LLVMMBlazeAsmPrinter
10
11 # Hack: we need to include 'main' MBlaze target directory to grab
12 # private headers
13 CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
14
15 include $(LEVEL)/Makefile.common
+0
-34
lib/Target/MBlaze/LLVMBuild.txt less more
None ;===- ./lib/Target/MBlaze/LLVMBuild.txt ------------------------*- Conf -*--===;
1 ;
2 ; The LLVM Compiler Infrastructure
3 ;
4 ; This file is distributed under the University of Illinois Open Source
5 ; License. See LICENSE.TXT for details.
6 ;
7 ;===------------------------------------------------------------------------===;
8 ;
9 ; This is an LLVMBuild description file for the components in this subdirectory.
10 ;
11 ; For more information on the LLVMBuild system, please see:
12 ;
13 ; http://llvm.org/docs/LLVMBuild.html
14 ;
15 ;===------------------------------------------------------------------------===;
16
17 [common]
18 subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
19
20 [component_0]
21 type = TargetGroup
22 name = MBlaze
23 parent = Target
24 has_asmparser = 1
25 has_asmprinter = 1
26 has_disassembler = 1
27
28 [component_1]
29 type = Library
30 name = MBlazeCodeGen
31 parent = MBlaze
32 required_libraries = AsmPrinter CodeGen Core MBlazeAsmPrinter MBlazeDesc MBlazeInfo MC SelectionDAG Support Target
33 add_to_library_groups = MBlaze
+0
-32
lib/Target/MBlaze/MBlaze.h less more
None //===-- MBlaze.h - Top-level interface for MBlaze ---------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the entry points for global functions defined in
10 // the LLVM MBlaze back-end.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef TARGET_MBLAZE_H
15 #define TARGET_MBLAZE_H
16
17 #include "MCTargetDesc/MBlazeBaseInfo.h"
18 #include "MCTargetDesc/MBlazeMCTargetDesc.h"
19 #include "llvm/Target/TargetMachine.h"
20
21 namespace llvm {
22 class MBlazeTargetMachine;
23 class FunctionPass;
24 class MachineCodeEmitter;
25
26 FunctionPass *createMBlazeISelDag(MBlazeTargetMachine &TM);
27 FunctionPass *createMBlazeDelaySlotFillerPass(MBlazeTargetMachine &TM);
28
29 } // end namespace llvm;
30
31 #endif
+0
-73
lib/Target/MBlaze/MBlaze.td less more
None //===-- MBlaze.td - Describe the MBlaze Target Machine -----*- tablegen -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 // This is the top level entry point for the MBlaze target.
9 //===----------------------------------------------------------------------===//
10
11 //===----------------------------------------------------------------------===//
12 // Target-independent interfaces
13 //===----------------------------------------------------------------------===//
14
15 include "llvm/Target/Target.td"
16
17 //===----------------------------------------------------------------------===//
18 // Register File, Calling Conv, Instruction Descriptions
19 //===----------------------------------------------------------------------===//
20
21 include "MBlazeRegisterInfo.td"
22 include "MBlazeSchedule.td"
23 include "MBlazeIntrinsics.td"
24 include "MBlazeInstrInfo.td"
25 include "MBlazeCallingConv.td"
26
27 def MBlazeInstrInfo : InstrInfo;
28
29 //===----------------------------------------------------------------------===//
30 // Microblaze Subtarget features //
31 //===----------------------------------------------------------------------===//
32
33 def FeatureBarrel : SubtargetFeature<"barrel", "HasBarrel", "true",
34 "Implements barrel shifter">;
35 def FeatureDiv : SubtargetFeature<"div", "HasDiv", "true",
36 "Implements hardware divider">;
37 def FeatureMul : SubtargetFeature<"mul", "HasMul", "true",
38 "Implements hardware multiplier">;
39 def FeaturePatCmp : SubtargetFeature<"patcmp", "HasPatCmp", "true",
40 "Implements pattern compare instruction">;
41 def FeatureFPU : SubtargetFeature<"fpu", "HasFPU", "true",
42 "Implements floating point unit">;
43 def FeatureMul64 : SubtargetFeature<"mul64", "HasMul64", "true",
44 "Implements multiplier with 64-bit result">;
45 def FeatureSqrt : SubtargetFeature<"sqrt", "HasSqrt", "true",
46 "Implements sqrt and floating point convert">;
47
48 //===----------------------------------------------------------------------===//
49 // MBlaze processors supported.
50 //===----------------------------------------------------------------------===//
51
52 def : Processor<"mblaze", NoItineraries, []>;
53 def : Processor<"mblaze3", MBlazePipe3Itineraries, []>;
54 def : Processor<"mblaze5", MBlazePipe5Itineraries, []>;
55
56 //===----------------------------------------------------------------------===//
57 // Instruction Descriptions
58 //===----------------------------------------------------------------------===//
59
60 def MBlazeAsmWriter : AsmWriter {
61 string AsmWriterClassName = "InstPrinter";
62 bit isMCAsmWriter = 1;
63 }
64
65 //===----------------------------------------------------------------------===//
66 // Target Declaration
67 //===----------------------------------------------------------------------===//
68
69 def MBlaze : Target {
70 let InstructionSet = MBlazeInstrInfo;
71 let AssemblyWriters = [MBlazeAsmWriter];
72 }
+0
-326
lib/Target/MBlaze/MBlazeAsmPrinter.cpp less more
None //===-- MBlazeAsmPrinter.cpp - MBlaze LLVM assembly writer ----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains a printer that converts from our internal representation
10 // of machine-dependent LLVM code to GAS-format MBlaze assembly language.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "mblaze-asm-printer"
15
16 #include "MBlaze.h"
17 #include "InstPrinter/MBlazeInstPrinter.h"
18 #include "MBlazeInstrInfo.h"
19 #include "MBlazeMCInstLower.h"
20 #include "MBlazeMachineFunction.h"
21 #include "MBlazeSubtarget.h"
22 #include "MBlazeTargetMachine.h"
23 #include "llvm/CodeGen/AsmPrinter.h"
24 #include "llvm/CodeGen/MachineConstantPool.h"
25 #include "llvm/CodeGen/MachineFrameInfo.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/MachineInstr.h"
28 #include "llvm/IR/Constants.h"
29 #include "llvm/IR/DataLayout.h"
30 #include "llvm/IR/DerivedTypes.h"
31 #include "llvm/IR/Module.h"
32 #include "llvm/MC/MCAsmInfo.h"
33 #include "llvm/MC/MCInst.h"
34 #include "llvm/MC/MCStreamer.h"
35 #include "llvm/MC/MCSymbol.h"
36 #include "llvm/Support/ErrorHandling.h"
37 #include "llvm/Support/TargetRegistry.h"
38 #include "llvm/Support/raw_ostream.h"
39 #include "llvm/Target/Mangler.h"
40 #include "llvm/Target/TargetLoweringObjectFile.h"
41 #include "llvm/Target/TargetMachine.h"
42 #include "llvm/Target/TargetOptions.h"
43 #include
44
45 using namespace llvm;
46
47 namespace {
48 class MBlazeAsmPrinter : public AsmPrinter {
49 const MBlazeSubtarget *Subtarget;
50 public:
51 explicit MBlazeAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
52 : AsmPrinter(TM, Streamer) {
53 Subtarget = &TM.getSubtarget();
54 }
55
56 virtual const char *getPassName() const {
57 return "MBlaze Assembly Printer";
58 }
59
60 void printSavedRegsBitmask();
61 void emitFrameDirective();
62 virtual void EmitFunctionBodyStart();
63 virtual void EmitFunctionBodyEnd();
64 virtual void EmitFunctionEntryLabel();
65
66 virtual bool isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
67 const;
68
69 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
70 unsigned AsmVariant, const char *ExtraCode,
71 raw_ostream &O);
72 void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
73 void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O);
74 void printFSLImm(const MachineInstr *MI, int opNum, raw_ostream &O);
75 void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
76 const char *Modifier = 0);
77
78 void EmitInstruction(const MachineInstr *MI);
79 };
80 } // end of anonymous namespace
81
82 // #include "MBlazeGenAsmWriter.inc"
83
84 //===----------------------------------------------------------------------===//
85 //
86 // MBlaze Asm Directives
87 //
88 // -- Frame directive "frame Stackpointer, Stacksize, RARegister"
89 // Describe the stack frame.
90 //
91 // -- Mask directives "mask bitmask, offset"
92 // Tells the assembler which registers are saved and where.
93 // bitmask - contain a little endian bitset indicating which registers are
94 // saved on function prologue (e.g. with a 0x80000000 mask, the
95 // assembler knows the register 31 (RA) is saved at prologue.
96 // offset - the position before stack pointer subtraction indicating where
97 // the first saved register on prologue is located. (e.g. with a
98 //
99 // Consider the following function prologue:
100 //
101 // .frame R19,48,R15
102 // .mask 0xc0000000,-8
103 // addiu R1, R1, -48
104 // sw R15, 40(R1)
105 // sw R19, 36(R1)
106 //
107 // With a 0xc0000000 mask, the assembler knows the register 15 (R15) and
108 // 19 (R19) are saved at prologue. As the save order on prologue is from
109 // left to right, R15 is saved first. A -8 offset means that after the
110 // stack pointer subtration, the first register in the mask (R15) will be
111 // saved at address 48-8=40.
112 //
113 //===----------------------------------------------------------------------===//
114
115 // Print a 32 bit hex number with all numbers.
116 static void printHex32(unsigned int Value, raw_ostream &O) {
117 O << "0x";
118 for (int i = 7; i >= 0; i--)
119 O.write_hex((Value & (0xF << (i*4))) >> (i*4));
120 }
121
122 // Create a bitmask with all callee saved registers for CPU or Floating Point
123 // registers. For CPU registers consider RA, GP and FP for saving if necessary.
124 void MBlazeAsmPrinter::printSavedRegsBitmask() {
125 const TargetFrameLowering *TFI = TM.getFrameLowering();
126 const TargetRegisterInfo &RI = *TM.getRegisterInfo();
127
128 // CPU Saved Registers Bitmasks
129 unsigned int CPUBitmask = 0;
130
131 // Set the CPU Bitmasks
132 const MachineFrameInfo *MFI = MF->getFrameInfo();
133 const std::vector &CSI = MFI->getCalleeSavedInfo();
134 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
135 unsigned Reg = CSI[i].getReg();
136 unsigned RegNum = getMBlazeRegisterNumbering(Reg);
137 if (MBlaze::GPRRegClass.contains(Reg))
138 CPUBitmask |= (1 << RegNum);
139 }
140
141 // Return Address and Frame registers must also be set in CPUBitmask.
142 if (TFI->hasFP(*MF))
143 CPUBitmask |= (1 << getMBlazeRegisterNumbering(RI.getFrameRegister(*MF)));
144
145 if (MFI->adjustsStack())
146 CPUBitmask |= (1 << getMBlazeRegisterNumbering(RI.getRARegister()));
147
148 // Print CPUBitmask
149 OutStreamer.EmitRawText("\t.mask\t0x" + Twine::utohexstr(CPUBitmask));
150 }
151
152 /// Frame Directive
153 void MBlazeAsmPrinter::emitFrameDirective() {
154 if (!OutStreamer.hasRawTextSupport())
155 return;
156
157 const TargetRegisterInfo &RI = *TM.getRegisterInfo();
158 unsigned stkReg = RI.getFrameRegister(*MF);
159 unsigned retReg = RI.getRARegister();
160 unsigned stkSze = MF->getFrameInfo()->getStackSize();
161
162 OutStreamer.EmitRawText("\t.frame\t" +
163 Twine(MBlazeInstPrinter::getRegisterName(stkReg)) +
164 "," + Twine(stkSze) + "," +
165 Twine(MBlazeInstPrinter::getRegisterName(retReg)));
166 }
167
168 void MBlazeAsmPrinter::EmitFunctionEntryLabel() {
169 if (OutStreamer.hasRawTextSupport())
170 OutStreamer.EmitRawText("\t.ent\t" + Twine(CurrentFnSym->getName()));
171 AsmPrinter::EmitFunctionEntryLabel();
172 }
173
174 void MBlazeAsmPrinter::EmitFunctionBodyStart() {
175 if (!OutStreamer.hasRawTextSupport())
176 return;
177
178 emitFrameDirective();
179 printSavedRegsBitmask();
180 }
181
182 void MBlazeAsmPrinter::EmitFunctionBodyEnd() {
183 if (OutStreamer.hasRawTextSupport())
184 OutStreamer.EmitRawText("\t.end\t" + Twine(CurrentFnSym->getName()));
185 }
186
187 //===----------------------------------------------------------------------===//
188 void MBlazeAsmPrinter::EmitInstruction(const MachineInstr *MI) {
189 MBlazeMCInstLower MCInstLowering(OutContext, *this);
190
191 MCInst TmpInst;
192 MCInstLowering.Lower(MI, TmpInst);
193 OutStreamer.EmitInstruction(TmpInst);
194 }
195
196 // Print out an operand for an inline asm expression.
197 bool MBlazeAsmPrinter::
198 PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
199 unsigned AsmVariant,const char *ExtraCode, raw_ostream &O) {
200 // Does this asm operand have a single letter operand modifier?
201 if (ExtraCode && ExtraCode[0])
202 if (ExtraCode[1] != 0) return true; // Unknown modifier.
203
204 switch (ExtraCode[0]) {
205 default:
206 // See if this is a generic print operand
207 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
208 }
209
210 printOperand(MI, OpNo, O);
211 return false;
212 }
213
214 void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
215 raw_ostream &O) {
216 const MachineOperand &MO = MI->getOperand(opNum);
217
218 switch (MO.getType()) {
219 case MachineOperand::MO_Register:
220 O << MBlazeInstPrinter::getRegisterName(MO.getReg());
221 break;
222
223 case MachineOperand::MO_Immediate:
224 O << (int32_t)MO.getImm();
225 break;
226
227 case MachineOperand::MO_FPImmediate: {
228 const ConstantFP *fp = MO.getFPImm();
229 printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue(), O);
230 O << ";\t# immediate = " << *fp;
231 break;
232 }
233
234 case MachineOperand::MO_MachineBasicBlock:
235 O << *MO.getMBB()->getSymbol();
236 return;
237
238 case MachineOperand::MO_GlobalAddress:
239 O << *Mang->getSymbol(MO.getGlobal());
240 break;
241
242 case MachineOperand::MO_ExternalSymbol:
243 O << *GetExternalSymbolSymbol(MO.getSymbolName());
244 break;
245
246 case MachineOperand::MO_JumpTableIndex:
247 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
248 << '_' << MO.getIndex();
249 break;
250
251 case MachineOperand::MO_ConstantPoolIndex:
252 O << MAI->getPrivateGlobalPrefix() << "CPI"
253 << getFunctionNumber() << "_" << MO.getIndex();
254 if (MO.getOffset())
255 O << "+" << MO.getOffset();
256 break;
257
258 default:
259 llvm_unreachable("");
260 }
261 }
262
263 void MBlazeAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
264 raw_ostream &O) {
265 const MachineOperand &MO = MI->getOperand(opNum);
266 if (MO.isImm())
267 O << (uint32_t)MO.getImm();
268 else
269 printOperand(MI, opNum, O);
270 }
271
272 void MBlazeAsmPrinter::printFSLImm(const MachineInstr *MI, int opNum,
273 raw_ostream &O) {
274 const MachineOperand &MO = MI->getOperand(opNum);
275 if (MO.isImm())
276 O << "rfsl" << (unsigned int)MO.getImm();
277 else
278 printOperand(MI, opNum, O);
279 }
280
281 void MBlazeAsmPrinter::
282 printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
283 const char *Modifier) {
284 printOperand(MI, opNum, O);
285 O << ", ";
286 printOperand(MI, opNum+1, O);
287 }
288
289 /// isBlockOnlyReachableByFallthough - Return true if the basic block has
290 /// exactly one predecessor and the control transfer mechanism between
291 /// the predecessor and this block is a fall-through.
292 bool MBlazeAsmPrinter::
293 isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
294 // If this is a landing pad, it isn't a fall through. If it has no preds,
295 // then nothing falls through to it.
296 if (MBB->isLandingPad() || MBB->pred_empty())
297 return false;
298
299 // If there isn't exactly one predecessor, it can't be a fall through.
300 MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
301 ++PI2;
302 if (PI2 != MBB->pred_end())
303 return false;
304
305 // The predecessor has to be immediately before this block.
306 const MachineBasicBlock *Pred = *PI;
307
308 if (!Pred->isLayoutSuccessor(MBB))
309 return false;
310
311 // If the block is completely empty, then it definitely does fall through.
312 if (Pred->empty())
313 return true;
314
315 // Check if the last terminator is an unconditional branch.
316 MachineBasicBlock::const_iterator I = Pred->end();
317 while (I != Pred->begin() && !(--I)->isTerminator())
318 ; // Noop
319 return I == Pred->end() || !I->isBarrier();
320 }
321
322 // Force static initialization.
323 extern "C" void LLVMInitializeMBlazeAsmPrinter() {
324 RegisterAsmPrinter X(TheMBlazeTarget);
325 }
+0
-24
lib/Target/MBlaze/MBlazeCallingConv.td less more
None //===- MBlazeCallingConv.td - Calling Conventions for MBlaze -*- tablegen -*-=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 // This describes the calling conventions for MBlaze architecture.
9 //===----------------------------------------------------------------------===//
10
11 //===----------------------------------------------------------------------===//
12 // MBlaze ABI Calling Convention
13 //===----------------------------------------------------------------------===//
14
15 def RetCC_MBlaze : CallingConv<[
16 // i32 are returned in registers R3, R4
17 CCIfType<[i32,f32], CCAssignToReg<[R3, R4]>>
18 ]>;
19
20 def CC_MBlaze : CallingConv<[
21 CCIfType<[i32,f32], CCCustom<"CC_MBlaze_AssignReg">>,
22 CCIfType<[i32,f32], CCAssignToStack<4, 4>>
23 ]>;
+0
-252
lib/Target/MBlaze/MBlazeDelaySlotFiller.cpp less more
None //===-- DelaySlotFiller.cpp - MBlaze delay slot filler --------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // A pass that attempts to fill instructions with delay slots. If no
10 // instructions can be moved into the delay slot then a NOP is placed there.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "delay-slot-filler"
15
16 #include "MBlaze.h"
17 #include "MBlazeTargetMachine.h"
18 #include "llvm/ADT/Statistic.h"
19 #include "llvm/CodeGen/MachineFunctionPass.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/Target/TargetInstrInfo.h"
26
27 using namespace llvm;
28
29 STATISTIC(FilledSlots, "Number of delay slots filled");
30
31 static cl::opt MBDisableDelaySlotFiller(
32 "disable-mblaze-delay-filler",
33 cl::init(false),
34 cl::desc("Disable the MBlaze delay slot filter."),
35 cl::Hidden);
36
37 namespace {
38 struct Filler : public MachineFunctionPass {
39 TargetMachine &TM;
40
41 static char ID;
42 Filler(TargetMachine &tm)
43 : MachineFunctionPass(ID), TM(tm) { }
44
45 virtual const char *getPassName() const {
46 return "MBlaze Delay Slot Filler";
47 }
48
49 bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
50 bool runOnMachineFunction(MachineFunction &F) {
51 bool Changed = false;
52 for (MachineFunction::iterator FI = F.begin(), FE = F.end();
53 FI != FE; ++FI)
54 Changed |= runOnMachineBasicBlock(*FI);
55 return Changed;
56 }
57
58 };
59 char Filler::ID = 0;
60 } // end of anonymous namespace
61
62 static bool hasImmInstruction(MachineBasicBlock::iterator &candidate) {
63 // Any instruction with an immediate mode operand greater than
64 // 16-bits requires an implicit IMM instruction.
65 unsigned numOper = candidate->getNumOperands();
66 for (unsigned op = 0; op < numOper; ++op) {
67 MachineOperand &mop = candidate->getOperand(op);
68
69 // The operand requires more than 16-bits to represent.
70 if (mop.isImm() && (mop.getImm() < -0x8000 || mop.getImm() > 0x7fff))
71 return true;
72
73 // We must assume that unknown immediate values require more than
74 // 16-bits to represent.
75 if (mop.isGlobal() || mop.isSymbol() || mop.isJTI() || mop.isCPI())
76 return true;
77
78 // FIXME: we could probably check to see if the FP value happens
79 // to not need an IMM instruction. For now we just always
80 // assume that FP values do.
81 if (mop.isFPImm())
82 return true;
83 }
84
85 return false;
86 }
87
88 static unsigned getLastRealOperand(MachineBasicBlock::iterator &instr) {
89 switch (instr->getOpcode()) {
90 default: return instr->getNumOperands();
91
92 // These instructions have a variable number of operands but the first two
93 // are the "real" operands that we care about during hazard detection.
94 case MBlaze::BRLID:
95 case MBlaze::BRALID:
96 case MBlaze::BRLD:
97 case MBlaze::BRALD:
98 return 2;
99 }
100 }
101
102 static bool delayHasHazard(MachineBasicBlock::iterator &candidate,
103 MachineBasicBlock::iterator &slot) {
104 // Hazard check
105 MachineBasicBlock::iterator a = candidate;
106 MachineBasicBlock::iterator b = slot;
107
108 // MBB layout:-
109 // candidate := a0 = operation(a1, a2)
110 // ...middle bit...
111 // slot := b0 = operation(b1, b2)
112
113 // Possible hazards:-/
114 // 1. a1 or a2 was written during the middle bit
115 // 2. a0 was read or written during the middle bit
116 // 3. a0 is one or more of {b0, b1, b2}
117 // 4. b0 is one or more of {a1, a2}
118 // 5. a accesses memory, and the middle bit
119 // contains a store operation.
120 bool a_is_memory = candidate->mayLoad() || candidate->mayStore();
121
122 // Determine the number of operands in the slot instruction and in the
123 // candidate instruction.
124 const unsigned aend = getLastRealOperand(a);
125 const unsigned bend = getLastRealOperand(b);
126
127 // Check hazards type 1, 2 and 5 by scanning the middle bit
128 MachineBasicBlock::iterator m = a;
129 for (++m; m != b; ++m) {
130 for (unsigned aop = 0; aop
131 bool aop_is_reg = a->getOperand(aop).isReg();
132 if (!aop_is_reg) continue;
133
134 bool aop_is_def = a->getOperand(aop).isDef();
135 unsigned aop_reg = a->getOperand(aop).getReg();
136
137 const unsigned mend = getLastRealOperand(m);
138 for (unsigned mop = 0; mop
139 bool mop_is_reg = m->getOperand(mop).isReg();
140 if (!mop_is_reg) continue;
141
142 bool mop_is_def = m->getOperand(mop).isDef();
143 unsigned mop_reg = m->getOperand(mop).getReg();
144
145 if (aop_is_def && (mop_reg == aop_reg))
146 return true; // Hazard type 2, because aop = a0
147 else if (mop_is_def && (mop_reg == aop_reg))
148 return true; // Hazard type 1, because aop in {a1, a2}
149 }
150 }
151
152 // Check hazard type 5
153 if (a_is_memory && m->mayStore())
154 return true;
155 }
156
157 // Check hazard type 3 & 4
158 for (unsigned aop = 0; aop
159 if (a->getOperand(aop).isReg()) {
160 unsigned aop_reg = a->getOperand(aop).getReg();
161
162 for (unsigned bop = 0; bop
163 if (b->getOperand(bop).isReg() && !b->getOperand(bop).isImplicit()) {
164 unsigned bop_reg = b->getOperand(bop).getReg();
165 if (aop_reg == bop_reg)
166 return true;
167 }
168 }
169 }
170 }
171
172 return false;
173 }
174
175 static bool isDelayFiller(MachineBasicBlock &MBB,
176 MachineBasicBlock::iterator candidate) {
177 if (candidate == MBB.begin())
178 return false;
179
180 --candidate;
181 return (candidate->hasDelaySlot());
182 }
183
184 static bool hasUnknownSideEffects(MachineBasicBlock::iterator &I) {
185 if (!I->hasUnmodeledSideEffects())
186 return false;
187
188 unsigned op = I->getOpcode();
189 if (op == MBlaze::ADDK || op == MBlaze::ADDIK ||
190 op == MBlaze::ADDC || op == MBlaze::ADDIC ||
191 op == MBlaze::ADDKC || op == MBlaze::ADDIKC ||
192 op == MBlaze::RSUBK || op == MBlaze::RSUBIK ||
193 op == MBlaze::RSUBC || op == MBlaze::RSUBIC ||
194 op == MBlaze::RSUBKC || op == MBlaze::RSUBIKC)
195 return false;
196
197 return true;
198 }
199
200 static MachineBasicBlock::iterator
201 findDelayInstr(MachineBasicBlock &MBB,MachineBasicBlock::iterator slot) {
202 MachineBasicBlock::iterator I = slot;
203 while (true) {
204 if (I == MBB.begin())
205 break;
206
207 --I;
208 if (I->hasDelaySlot() || I->isBranch() || isDelayFiller(MBB,I) ||
209 I->isCall() || I->isReturn() || I->isBarrier() ||
210 hasUnknownSideEffects(I))
211 break;
212
213 if (hasImmInstruction(I) || delayHasHazard(I,slot))
214 continue;
215
216 return I;
217 }
218
219 return MBB.end();
220 }
221
222 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
223 /// Currently, we fill delay slots with NOPs. We assume there is only one
224 /// delay slot per delayed instruction.
225 bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
226 bool Changed = false;
227 for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
228 if (I->hasDelaySlot()) {
229 MachineBasicBlock::iterator D = MBB.end();
230 MachineBasicBlock::iterator J = I;
231
232 if (!MBDisableDelaySlotFiller)
233 D = findDelayInstr(MBB,I);
234
235 ++FilledSlots;
236 Changed = true;
237
238 if (D == MBB.end())
239 BuildMI(MBB, ++J, I->getDebugLoc(),TM.getInstrInfo()->get(MBlaze::NOP));
240 else
241 MBB.splice(++J, &MBB, D);
242 }
243 return Changed;
244 }
245
246 /// createMBlazeDelaySlotFillerPass - Returns a pass that fills in delay
247 /// slots in MBlaze MachineFunctions
248 FunctionPass *llvm::createMBlazeDelaySlotFillerPass(MBlazeTargetMachine &tm) {
249 return new Filler(tm);
250 }
251
+0
-488
lib/Target/MBlaze/MBlazeFrameLowering.cpp less more
None //===-- MBlazeFrameLowering.cpp - MBlaze Frame Information ---------------====//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the MBlaze implementation of TargetFrameLowering class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #define DEBUG_TYPE "mblaze-frame-lowering"
14
15 #include "MBlazeFrameLowering.h"
16 #include "InstPrinter/MBlazeInstPrinter.h"
17 #include "MBlazeInstrInfo.h"
18 #include "MBlazeMachineFunction.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/IR/DataLayout.h"
25 #include "llvm/IR/Function.h"
26 #include "llvm/Support/CommandLine.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include "llvm/Target/TargetOptions.h"
31
32 using namespace llvm;
33
34 static cl::opt MBDisableStackAdjust(
35 "disable-mblaze-stack-adjust",
36 cl::init(false),
37 cl::desc("Disable MBlaze stack layout adjustment."),
38 cl::Hidden);
39
40 static void replaceFrameIndexes(MachineFunction &MF,
41 SmallVectorImpl > &FR) {
42 MachineFrameInfo *MFI = MF.getFrameInfo();
43 MBlazeFunctionInfo *MBlazeFI = MF.getInfo();
44 const SmallVectorImpl >::iterator FRB = FR.begin();
45 const SmallVectorImpl >::iterator FRE = FR.end();
46
47 SmallVectorImpl >::iterator FRI = FRB;
48 for (; FRI != FRE; ++FRI) {
49 MFI->RemoveStackObject(FRI->first);
50 int NFI = MFI->CreateFixedObject(4, FRI->second, true);
51 MBlazeFI->recordReplacement(FRI->first, NFI);
52
53 for (MachineFunction::iterator MB=MF.begin(), ME=MF.end(); MB!=ME; ++MB) {
54 MachineBasicBlock::iterator MBB = MB->begin();
55 const MachineBasicBlock::iterator MBE = MB->end();
56
57 for (; MBB != MBE; ++MBB) {
58 MachineInstr::mop_iterator MIB = MBB->operands_begin();
59 const MachineInstr::mop_iterator MIE = MBB->operands_end();
60
61 for (MachineInstr::mop_iterator MII = MIB; MII != MIE; ++MII) {
62 if (!MII->isFI() || MII->getIndex() != FRI->first) continue;
63 DEBUG(dbgs() << "FOUND FI#" << MII->getIndex() << "\n");
64 MII->setIndex(NFI);
65 }
66 }
67 }
68 }
69 }
70
71 //===----------------------------------------------------------------------===//
72 //
73 // Stack Frame Processing methods
74 // +----------------------------+
75 //
76 // The stack is allocated decrementing the stack pointer on
77 // the first instruction of a function prologue. Once decremented,
78 // all stack references are are done through a positive offset
79 // from the stack/frame pointer, so the stack is considered
80 // to grow up.
81 //
82 //===----------------------------------------------------------------------===//
83
84 static void analyzeFrameIndexes(MachineFunction &MF) {
85 if (MBDisableStackAdjust) return;
86
87 MachineFrameInfo *MFI = MF.getFrameInfo();
88 MBlazeFunctionInfo *MBlazeFI = MF.getInfo();
89 const MachineRegisterInfo &MRI = MF.getRegInfo();
90
91 MachineRegisterInfo::livein_iterator LII = MRI.livein_begin();
92 MachineRegisterInfo::livein_iterator LIE = MRI.livein_end();
93 const SmallVectorImpl &LiveInFI = MBlazeFI->getLiveIn();
94 SmallVector EraseInstr;
95 SmallVector, 16> FrameRelocate;
96
97 MachineBasicBlock *MBB = MF.getBlockNumbered(0);
98 MachineBasicBlock::iterator MIB = MBB->begin();
99 MachineBasicBlock::iterator MIE = MBB->end();
100
101 int StackAdjust = 0;
102 int StackOffset = -28;
103
104 // In this loop we are searching frame indexes that corrospond to incoming
105 // arguments that are already in the stack. We look for instruction sequences
106 // like the following:
107 //
108 // LWI REG, FI1, 0
109 // ...
110 // SWI REG, FI2, 0
111 //
112 // As long as there are no defs of REG in the ... part, we can eliminate
113 // the SWI instruction because the value has already been stored to the
114 // stack by the caller. All we need to do is locate FI at the correct
115 // stack location according to the calling convensions.
116 //
117 // Additionally, if the SWI operation kills the def of REG then we don't
118 // need the LWI operation so we can erase it as well.
119 for (unsigned i = 0, e = LiveInFI.size(); i < e; ++i) {
120 for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
121 if (I->getOpcode() != MBlaze::LWI || I->getNumOperands() != 3 ||
122 !I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
123 I->getOperand(1).getIndex() != LiveInFI[i]) continue;
124
125 unsigned FIReg = I->getOperand(0).getReg();
126 MachineBasicBlock::iterator SI = I;
127 for (SI++; SI != MIE; ++SI) {
128 if (!SI->getOperand(0).isReg() ||
129 !SI->getOperand(1).isFI() ||
130 SI->getOpcode() != MBlaze::SWI) continue;
131
132 int FI = SI->getOperand(1).getIndex();
133 if (SI->getOperand(0).getReg() != FIReg ||
134 MFI->isFixedObjectIndex(FI) ||
135 MFI->getObjectSize(FI) != 4) continue;
136
137 if (SI->getOperand(0).isDef()) break;
138
139 if (SI->getOperand(0).isKill()) {
140 DEBUG(dbgs() << "LWI for FI#" << I->getOperand(1).getIndex()
141 << " removed\n");
142 EraseInstr.push_back(I);
143 }
144
145 EraseInstr.push_back(SI);
146 DEBUG(dbgs() << "SWI for FI#" << FI << " removed\n");
147
148 FrameRelocate.push_back(std::make_pair(FI,StackOffset));
149 DEBUG(dbgs() << "FI#" << FI << " relocated to " << StackOffset << "\n");
150
151 StackOffset -= 4;
152 StackAdjust += 4;
153 break;
154 }
155 }
156 }
157
158 // In this loop we are searching for frame indexes that corrospond to
159 // incoming arguments that are in registers. We look for instruction
160 // sequences like the following:
161 //
162 // ... SWI REG, FI, 0
163 //
164 // As long as the ... part does not define REG and if REG is an incoming
165 // parameter register then we know that, according to ABI convensions, the
166 // caller has allocated stack space for it already. Instead of allocating
167 // stack space on our frame, we record the correct location in the callers
168 // frame.
169 for (MachineRegisterInfo::livein_iterator LI = LII; LI != LIE; ++LI) {
170 for (MachineBasicBlock::iterator I=MIB; I != MIE; ++I) {
171 if (I->definesRegister(LI->first))
172 break;
173
174 if (I->getOpcode() != MBlaze::SWI || I->getNumOperands() != 3 ||
175 !I->getOperand(1).isFI() || !I->getOperand(0).isReg() ||
176 I->getOperand(1).getIndex() < 0) continue;
177
178 if (I->getOperand(0).getReg() == LI->first) {
179 int FI = I->getOperand(1).getIndex();
180 MBlazeFI->recordLiveIn(FI);
181
182 int FILoc = 0;
183 switch (LI->first) {
184 default: llvm_unreachable("invalid incoming parameter!");
185 case MBlaze::R5: FILoc = -4; break;
186 case MBlaze::R6: FILoc = -8; break;
187 case MBlaze::R7: FILoc = -12; break;
188 case MBlaze::R8: FILoc = -16; break;
189 case MBlaze::R9: FILoc = -20; break;
190 case MBlaze::R10: FILoc = -24; break;
191 }
192
193 StackAdjust += 4;
194 FrameRelocate.push_back(std::make_pair(FI,FILoc));
195 DEBUG(dbgs() << "FI#" << FI << " relocated to " << FILoc << "\n");
196 break;
197 }
198 }
199 }
200
201 // Go ahead and erase all of the instructions that we determined were
202 // no longer needed.
203 for (int i = 0, e = EraseInstr.size(); i < e; ++i)
204 MBB->erase(EraseInstr[i]);
205
206 // Replace all of the frame indexes that we have relocated with new
207 // fixed object frame indexes.
208 replaceFrameIndexes(MF, FrameRelocate);
209 }
210
211 static void interruptFrameLayout(MachineFunction &MF) {
212 const Function *F = MF.getFunction();
213 CallingConv::ID CallConv = F->getCallingConv();
214
215 // If this function is not using either the interrupt_handler
216 // calling convention or the save_volatiles calling convention
217 // then we don't need to do any additional frame layout.
218 if (CallConv != CallingConv::MBLAZE_INTR &&
219 CallConv != CallingConv::MBLAZE_SVOL)
220 return;
221
222 MachineFrameInfo *MFI = MF.getFrameInfo();
223 const MachineRegisterInfo &MRI = MF.getRegInfo();
224 const MBlazeInstrInfo &TII =
225 *static_cast(MF.getTarget().getInstrInfo());
226
227 // Determine if the calling convention is the interrupt_handler
228 // calling convention. Some pieces of the prologue and epilogue
229 // only need to be emitted if we are lowering and interrupt handler.
230 bool isIntr = CallConv == CallingConv::MBLAZE_INTR;
231
232 // Determine where to put prologue and epilogue additions
233 MachineBasicBlock &MENT = MF.front();
234 MachineBasicBlock &MEXT = MF.back();
235
236 MachineBasicBlock::iterator MENTI = MENT.begin();
237 MachineBasicBlock::iterator MEXTI = prior(MEXT.end());
238
239 DebugLoc ENTDL = MENTI != MENT.end() ? MENTI->getDebugLoc() : DebugLoc();
240 DebugLoc EXTDL = MEXTI != MEXT.end() ? MEXTI->getDebugLoc() : DebugLoc();
241
242 // Store the frame indexes generated during prologue additions for use
243 // when we are generating the epilogue additions.
244 SmallVector VFI;
245
246 // Build the prologue SWI for R3 - R12 if needed. Note that R11 must
247 // always have a SWI because it is used when processing RMSR.
248 for (unsigned r = MBlaze::R3; r <= MBlaze::R12; ++r) {
249 if (!MRI.isPhysRegUsed(r) && !(isIntr && r == MBlaze::R11)) continue;
250
251 int FI = MFI->CreateStackObject(4,4,false,false);
252 VFI.push_back(FI);
253
254 BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), r)
255 .addFrameIndex(FI).addImm(0);
256 }
257
258 // Build the prologue SWI for R17, R18
259 int R17FI = MFI->CreateStackObject(4,4,false,false);
260 int R18FI = MFI->CreateStackObject(4,4,false,false);
261
262 BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R17)
263 .addFrameIndex(R17FI).addImm(0);
264
265 BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R18)
266 .addFrameIndex(R18FI).addImm(0);
267
268 // Buid the prologue SWI and the epilogue LWI for RMSR if needed
269 if (isIntr) {
270 int MSRFI = MFI->CreateStackObject(4,4,false,false);
271 BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::MFS), MBlaze::R11)
272 .addReg(MBlaze::RMSR);
273 BuildMI(MENT, MENTI, ENTDL, TII.get(MBlaze::SWI), MBlaze::R11)
274 .addFrameIndex(MSRFI).addImm(0);
275
276 BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R11)
277 .addFrameIndex(MSRFI).addImm(0);
278 BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::MTS), MBlaze::RMSR)
279 .addReg(MBlaze::R11);
280 }
281
282 // Build the epilogue LWI for R17, R18
283 BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R18)
284 .addFrameIndex(R18FI).addImm(0);
285
286 BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), MBlaze::R17)
287 .addFrameIndex(R17FI).addImm(0);
288
289 // Build the epilogue LWI for R3 - R12 if needed
290 for (unsigned r = MBlaze::R12, i = VFI.size(); r >= MBlaze::R3; --r) {
291 if (!MRI.isPhysRegUsed(r)) continue;
292 BuildMI(MEXT, MEXTI, EXTDL, TII.get(MBlaze::LWI), r)
293 .addFrameIndex(VFI[--i]).addImm(0);
294 }
295 }
296
297 static void determineFrameLayout(MachineFunction &MF) {
298 MachineFrameInfo *MFI = MF.getFrameInfo();
299 MBlazeFunctionInfo *MBlazeFI = MF.getInfo();
300
301 // Replace the dummy '0' SPOffset by the negative offsets, as explained on
302 // LowerFORMAL_ARGUMENTS. Leaving '0' for while is necessary to avoid
303 // the approach done by calculateFrameObjectOffsets to the stack frame.
304 MBlazeFI->adjustLoadArgsFI(MFI);
305 MBlazeFI->adjustStoreVarArgsFI(MFI);
306
307 // Get the number of bytes to allocate from the FrameInfo
308 unsigned FrameSize = MFI->getStackSize();
309 DEBUG(dbgs() << "Original Frame Size: " << FrameSize << "\n" );
310
311 // Get the alignments provided by the target, and the maximum alignment
312 // (if any) of the fixed frame objects.
313 // unsigned MaxAlign = MFI->getMaxAlignment();
314 unsigned TargetAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
315 unsigned AlignMask = TargetAlign - 1;
316
317 // Make sure the frame is aligned.
318 FrameSize = (FrameSize + AlignMask) & ~AlignMask;
319 MFI->setStackSize(FrameSize);
320 DEBUG(dbgs() << "Aligned Frame Size: " << FrameSize << "\n" );
321 }
322
323 int MBlazeFrameLowering::getFrameIndexOffset(const MachineFunction &MF, int FI)
324 const {
325 const MBlazeFunctionInfo *MBlazeFI = MF.getInfo();
326 if (MBlazeFI->hasReplacement(FI))
327 FI = MBlazeFI->getReplacement(FI);
328 return TargetFrameLowering::getFrameIndexOffset(MF,FI);
329 }
330
331 // hasFP - Return true if the specified function should have a dedicated frame
332 // pointer register. This is true if the function has variable sized allocas or
333 // if frame pointer elimination is disabled.
334 bool MBlazeFrameLowering::hasFP(const MachineFunction &MF) const {
335 const MachineFrameInfo *MFI = MF.getFrameInfo();
336 return MF.getTarget().Options.DisableFramePointerElim(MF) ||
337 MFI->hasVarSizedObjects();
338 }
339
340 void MBlazeFrameLowering::emitPrologue(MachineFunction &MF) const {
341 MachineBasicBlock &MBB = MF.front();
342 MachineFrameInfo *MFI = MF.getFrameInfo();
343 const MBlazeInstrInfo &TII =
344 *static_cast(MF.getTarget().getInstrInfo());
345 MBlazeFunctionInfo *MBlazeFI = MF.getInfo();
346 MachineBasicBlock::iterator MBBI = MBB.begin();
347 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
348
349 CallingConv::ID CallConv = MF.getFunction()->getCallingConv();
350 bool requiresRA = CallConv == CallingConv::MBLAZE_INTR;
351
352 // Determine the correct frame layout
353 determineFrameLayout(MF);
354
355 // Get the number of bytes to allocate from the FrameInfo.
356 unsigned StackSize = MFI->getStackSize();
357
358 // No need to allocate space on the stack.
359 if (StackSize == 0 && !MFI->adjustsStack() && !requiresRA) return;
360
361 int FPOffset = MBlazeFI->getFPStackOffset();
362 int RAOffset = MBlazeFI->getRAStackOffset();
363
364 // Adjust stack : addi R1, R1, -imm
365 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADDIK), MBlaze::R1)
366 .addReg(MBlaze::R1).addImm(-StackSize);
367
368 // swi R15, R1, stack_loc
369 if (MFI->adjustsStack() || requiresRA) {
370 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
371 .addReg(MBlaze::R15).addReg(MBlaze::R1).addImm(RAOffset);
372 }
373
374 if (hasFP(MF)) {
375 // swi R19, R1, stack_loc
376 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::SWI))
377 .addReg(MBlaze::R19).addReg(MBlaze::R1).addImm(FPOffset);
378
379 // add R19, R1, R0
380 BuildMI(MBB, MBBI, DL, TII.get(MBlaze::ADD), MBlaze::R19)
381 .addReg(MBlaze::R1).addReg(MBlaze::R0);
382 }
383 }
384
385 void MBlazeFrameLowering::emitEpilogue(MachineFunction &MF,
386 MachineBasicBlock &MBB) const {
387 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
388 MachineFrameInfo *MFI = MF.getFrameInfo();
389 MBlazeFunctionInfo *MBlazeFI = MF.getInfo();
390 const MBlazeInstrInfo &TII =
391 *static_cast(MF.getTarget().getInstrInfo());
392
393 DebugLoc dl = MBBI->getDebugLoc();
394
395 CallingConv::ID CallConv = MF.getFunction()->getCallingConv();
396 bool requiresRA = CallConv == CallingConv::MBLAZE_INTR;
397
398 // Get the FI's where RA and FP are saved.
399 int FPOffset = MBlazeFI->getFPStackOffset();
400 int RAOffset = MBlazeFI->getRAStackOffset();
401
402 if (hasFP(MF)) {
403 // add R1, R19, R0
404 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADD), MBlaze::R1)
405 .addReg(MBlaze::R19).addReg(MBlaze::R0);
406
407 // lwi R19, R1, stack_loc
408 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R19)
409 .addReg(MBlaze::R1).addImm(FPOffset);
410 }
411
412 // lwi R15, R1, stack_loc
413 if (MFI->adjustsStack() || requiresRA) {
414 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::LWI), MBlaze::R15)
415 .addReg(MBlaze::R1).addImm(RAOffset);
416 }
417
418 // Get the number of bytes from FrameInfo
419 int StackSize = (int) MFI->getStackSize();
420
421 // addi R1, R1, imm
422 if (StackSize) {
423 BuildMI(MBB, MBBI, dl, TII.get(MBlaze::ADDIK), MBlaze::R1)
424 .addReg(MBlaze::R1).addImm(StackSize);
425 }
426 }
427
428 // Eliminate ADJCALLSTACKDOWN/ADJCALLSTACKUP pseudo instructions
429 void MBlazeFrameLowering::
430 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
431 MachineBasicBlock::iterator I) const {
432 const MBlazeInstrInfo &TII =
433 *static_cast(MF.getTarget().getInstrInfo());
434 if (!hasReservedCallFrame(MF)) {
435 // If we have a frame pointer, turn the adjcallstackup instruction into a
436 // 'addi r1, r1, -' and the adjcallstackdown instruction into
437 // 'addi r1, r1, '
438 MachineInstr *Old = I;
439 int Amount = Old->getOperand(0).getImm() + 4;
440 if (Amount != 0) {
441 // We need to keep the stack aligned properly. To do this, we round the
442 // amount of space needed for the outgoing arguments up to the next
443 // alignment boundary.
444 unsigned Align = getStackAlignment();
445 Amount = (Amount+Align-1)/Align*Align;
446
447 MachineInstr *New;
448 if (Old->getOpcode() == MBlaze::ADJCALLSTACKDOWN) {
449 New = BuildMI(MF,Old->getDebugLoc(), TII.get(MBlaze::ADDIK),MBlaze::R1)
450 .addReg(MBlaze::R1).addImm(-Amount);
451 } else {
452 assert(Old->getOpcode() == MBlaze::ADJCALLSTACKUP);
453 New = BuildMI(MF,Old->getDebugLoc(), TII.get(MBlaze::ADDIK),MBlaze::R1)
454 .addReg(MBlaze::R1).addImm(Amount);
455 }
456
457 // Replace the pseudo instruction with a new instruction...
458 MBB.insert(I, New);
459 }
460 }
461
462 // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
463 MBB.erase(I);
464 }
465
466
467 void MBlazeFrameLowering::
468 processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
469 RegScavenger *RS) const {
470 MachineFrameInfo *MFI = MF.getFrameInfo();
471 MBlazeFunctionInfo *MBlazeFI = MF.getInfo();
472 CallingConv::ID CallConv = MF.getFunction()->getCallingConv();
473 bool requiresRA = CallConv == CallingConv::MBLAZE_INTR;
474
475 if (MFI->adjustsStack() || requiresRA) {
476 MBlazeFI->setRAStackOffset(0);
477 MFI->CreateFixedObject(4,0,true);
478 }
479
480 if (hasFP(MF)) {
481 MBlazeFI->setFPStackOffset(4);
482 MFI->CreateFixedObject(4,4,true);
483 }
484
485 interruptFrameLayout(MF);
486 analyzeFrameIndexes(MF);
487 }
+0
-56
lib/Target/MBlaze/MBlazeFrameLowering.h less more
None //=- MBlazeFrameLowering.h - Define frame lowering for MicroBlaze -*- C++ -*-=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef MBLAZE_FRAMEINFO_H
14 #define MBLAZE_FRAMEINFO_H
15
16 #include "MBlaze.h"
17 #include "llvm/Target/TargetFrameLowering.h"
18
19 namespace llvm {
20 class MBlazeSubtarget;
21
22 class MBlazeFrameLowering : public TargetFrameLowering {
23 protected:
24 const MBlazeSubtarget &STI;
25
26 public:
27 explicit MBlazeFrameLowering(const MBlazeSubtarget &sti)
28 : TargetFrameLowering(TargetFrameLowering::StackGrowsUp, 4, 0), STI(sti) {
29 }
30
31 /// targetHandlesStackFrameRounding - Returns true if the target is
32 /// responsible for rounding up the stack frame (probably at emitPrologue
33 /// time).
34 bool targetHandlesStackFrameRounding() const { return true; }
35
36 /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
37 /// the function.
38 void emitPrologue(MachineFunction &MF) const;
39 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
40
41 void eliminateCallFramePseudoInstr(MachineFunction &MF,
42 MachineBasicBlock &MBB,
43 MachineBasicBlock::iterator I) const;
44
45 bool hasFP(const MachineFunction &MF) const;
46
47 int getFrameIndexOffset(const MachineFunction &MF, int FI) const;
48
49 virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
50 RegScavenger *RS) const;
51 };
52
53 } // End llvm namespace
54
55 #endif
+0
-278
lib/Target/MBlaze/MBlazeISelDAGToDAG.cpp less more
None //===-- MBlazeISelDAGToDAG.cpp - A dag to dag inst selector for MBlaze ----===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines an instruction selector for the MBlaze target.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #define DEBUG_TYPE "mblaze-isel"
14 #include "MBlaze.h"
15 #include "MBlazeMachineFunction.h"
16 #include "MBlazeRegisterInfo.h"
17 #include "MBlazeSubtarget.h"
18 #include "MBlazeTargetMachine.h"
19 #include "llvm/CodeGen/MachineConstantPool.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/SelectionDAGISel.h"
25 #include "llvm/IR/GlobalValue.h"
26 #include "llvm/IR/Instructions.h"
27 #include "llvm/IR/Intrinsics.h"
28 #include "llvm/IR/Type.h"
29 #include "llvm/Support/CFG.h"
30 #include "llvm/Support/Debug.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/Target/TargetMachine.h"
34 using namespace llvm;
35
36 //===----------------------------------------------------------------------===//
37 // Instruction Selector Implementation
38 //===----------------------------------------------------------------------===//
39
40 //===----------------------------------------------------------------------===//
41 // MBlazeDAGToDAGISel - MBlaze specific code to select MBlaze machine
42 // instructions for SelectionDAG operations.
43 //===----------------------------------------------------------------------===//
44 namespace {
45
46 class MBlazeDAGToDAGISel : public SelectionDAGISel {
47
48 /// TM - Keep a reference to MBlazeTargetMachine.
49 MBlazeTargetMachine &TM;
50
51 /// Subtarget - Keep a pointer to the MBlazeSubtarget around so that we can
52 /// make the right decision when generating code for different targets.
53 const MBlazeSubtarget &Subtarget;
54
55 public:
56 explicit MBlazeDAGToDAGISel(MBlazeTargetMachine &tm) :
57 SelectionDAGISel(tm),
58 TM(tm), Subtarget(tm.getSubtarget()) {}
59
60 // Pass Name
61 virtual const char *getPassName() const {
62 return "MBlaze DAG->DAG Pattern Instruction Selection";
63 }
64 private:
65 // Include the pieces autogenerated from the target description.
66 #include "MBlazeGenDAGISel.inc"
67
68 /// getTargetMachine - Return a reference to the TargetMachine, casted
69 /// to the target-specific type.
70 const MBlazeTargetMachine &getTargetMachine() {
71 return static_cast(TM);
72 }
73
74 /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
75 /// to the target-specific type.
76 const MBlazeInstrInfo *getInstrInfo() {
77 return getTargetMachine().getInstrInfo();
78 }
79
80 SDNode *getGlobalBaseReg();
81 SDNode *Select(SDNode *N);
82
83 // Address Selection
84 bool SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index);
85 bool SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base);
86
87 // getI32Imm - Return a target constant with the specified value, of type i32.
88 inline SDValue getI32Imm(unsigned Imm) {
89 return CurDAG->getTargetConstant(Imm, MVT::i32);
90 }
91 };
92
93 }
94
95 /// isIntS32Immediate - This method tests to see if the node is either a 32-bit
96 /// or 64-bit immediate, and if the value can be accurately represented as a
97 /// sign extension from a 32-bit value. If so, this returns true and the
98 /// immediate.
99 static bool isIntS32Immediate(SDNode *N, int32_t &Imm) {
100 unsigned Opc = N->getOpcode();
101 if (Opc != ISD::Constant)
102 return false;
103
104 Imm = (int32_t)cast(N)->getZExtValue();
105 if (N->getValueType(0) == MVT::i32)
106 return Imm == (int32_t)cast(N)->getZExtValue();
107 else
108 return Imm == (int64_t)cast(N)->getZExtValue();
109 }
110
111 static bool isIntS32Immediate(SDValue Op, int32_t &Imm) {
112 return isIntS32Immediate(Op.getNode(), Imm);
113 }
114
115
116 /// SelectAddressRegReg - Given the specified addressed, check to see if it
117 /// can be represented as an indexed [r+r] operation. Returns false if it
118 /// can be more efficiently represented with [r+imm].
119 bool MBlazeDAGToDAGISel::
120 SelectAddrRegReg(SDValue N, SDValue &Base, SDValue &Index) {
121 if (N.getOpcode() == ISD::FrameIndex) return false;
122 if (N.getOpcode() == ISD::TargetExternalSymbol ||
123 N.getOpcode() == ISD::TargetGlobalAddress)
124 return false; // direct calls.
125
126 int32_t imm = 0;
127 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
128 if (isIntS32Immediate(N.getOperand(1), imm))
129 return false; // r+i
130
131 if (N.getOperand(0).getOpcode() == ISD::TargetJumpTable ||
132 N.getOperand(1).getOpcode() == ISD::TargetJumpTable)
133 return false; // jump tables.
134
135 Base = N.getOperand(0);
136 Index = N.getOperand(1);
137 return true;
138 }
139
140 return false;
141 }
142
143 /// Returns true if the address N can be represented by a base register plus
144 /// a signed 32-bit displacement [r+imm], and if it is not better
145 /// represented as reg+reg.
146 bool MBlazeDAGToDAGISel::
147 SelectAddrRegImm(SDValue N, SDValue &Base, SDValue &Disp) {
148 // If this can be more profitably realized as r+r, fail.
149 if (SelectAddrRegReg(N, Base, Disp))
150 return false;
151
152 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
153 int32_t imm = 0;
154 if (isIntS32Immediate(N.getOperand(1), imm)) {
155 Disp = CurDAG->getTargetConstant(imm, MVT::i32);
156 if (FrameIndexSDNode *FI = dyn_cast(N.getOperand(0))) {
157 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType());
158 } else {
159 Base = N.getOperand(0);
160 }
161 return true; // [r+i]
162 }
163 } else if (ConstantSDNode *CN = dyn_cast(N)) {
164 // Loading from a constant address.
165 uint32_t Imm = CN->getZExtValue();
166 Disp = CurDAG->getTargetConstant(Imm, CN->getValueType(0));
167 Base = CurDAG->getRegister(MBlaze::R0, CN->getValueType(0));
168 return true;
169 }
170
171 Disp = CurDAG->getTargetConstant(0, TM.getTargetLowering()->getPointerTy());
172 if (FrameIndexSDNode *FI = dyn_cast(N))
173 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType());
174 else
175 Base = N;
176 return true; // [r+0]
177 }
178
179 /// getGlobalBaseReg - Output the instructions required to put the
180 /// GOT address into a register.
181 SDNode *MBlazeDAGToDAGISel::getGlobalBaseReg() {
182 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
183 return CurDAG->getRegister(GlobalBaseReg,
184 getTargetLowering()->getPointerTy()).getNode();
185 }
186
187 /// Select instructions not customized! Used for
188 /// expanded, promoted and normal instructions
189 SDNode* MBlazeDAGToDAGISel::Select(SDNode *Node) {
190 unsigned Opcode = Node->getOpcode();
191 SDLoc dl(Node);
192
193 // If we have a custom node, we already have selected!
194 if (Node->isMachineOpcode())
195 return NULL;
196
197 ///
198 // Instruction Selection not handled by the auto-generated
199 // tablegen selection should be handled here.
200 ///
201 switch (Opcode) {
202 default: break;
203
204 // Get target GOT address.
205 case ISD::GLOBAL_OFFSET_TABLE:
206 return getGlobalBaseReg();
207
208 case ISD::FrameIndex: {
209 SDValue imm = CurDAG->getTargetConstant(0, MVT::i32);
210 int FI = dyn_cast(Node)->getIndex();
211 EVT VT = Node->getValueType(0);
212 SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
213 unsigned Opc = MBlaze::ADDIK;
214 if (Node->hasOneUse())
215 return CurDAG->SelectNodeTo(Node, Opc, VT, TFI, imm);
216 return CurDAG->getMachineNode(Opc, dl, VT, TFI, imm);
217 }
218
219
220 /// Handle direct and indirect calls when using PIC. On PIC, when
221 /// GOT is smaller than about 64k (small code) the GA target is
222 /// loaded with only one instruction. Otherwise GA's target must
223 /// be loaded with 3 instructions.
224 case MBlazeISD::JmpLink: {
225 if (TM.getRelocationModel() == Reloc::PIC_) {
226 SDValue Chain = Node->getOperand(0);
227 SDValue Callee = Node->getOperand(1);
228 SDValue R20Reg = CurDAG->getRegister(MBlaze::R20, MVT::i32);
229 SDValue InFlag(0, 0);
230
231 if ((isa(Callee)) ||
232 (isa(Callee)))
233 {
234 /// Direct call for global addresses and external symbols
235 SDValue GPReg = CurDAG->getRegister(MBlaze::R15, MVT::i32);
236
237 // Use load to get GOT target
238 SDValue Ops[] = { Callee, GPReg, Chain };
239 SDValue Load = SDValue(CurDAG->getMachineNode(MBlaze::LW, dl,
240 MVT::i32, MVT::Other, Ops), 0);
241 Chain = Load.getValue(1);
242
243 // Call target must be on T9
244 Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Load, InFlag);
245 } else
246 /// Indirect call
247 Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Callee, InFlag);
248
249 // Emit Jump and Link Register
250 SDNode *ResNode = CurDAG->getMachineNode(MBlaze::BRLID, dl, MVT::Other,
251 MVT::Glue, R20Reg, Chain);
252 Chain = SDValue(ResNode, 0);
253 InFlag = SDValue(ResNode, 1);
254 ReplaceUses(SDValue(Node, 0), Chain);
255 ReplaceUses(SDValue(Node, 1), InFlag);
256 return ResNode;
257 }
258 }
259 }
260
261 // Select the default instruction
262 SDNode *ResNode = SelectCode(Node);
263
264 DEBUG(errs() << "=> ");
265 if (ResNode == NULL || ResNode == Node)
266 DEBUG(Node->dump(CurDAG));
267 else
268 DEBUG(ResNode->dump(CurDAG));
269 DEBUG(errs() << "\n");
270 return ResNode;
271 }
272
273 /// createMBlazeISelDag - This pass converts a legalized DAG into a
274 /// MBlaze-specific DAG, ready for instruction scheduling.
275 FunctionPass *llvm::createMBlazeISelDag(MBlazeTargetMachine &TM) {
276 return new MBlazeDAGToDAGISel(TM);
277 }
+0
-1155
lib/Target/MBlaze/MBlazeISelLowering.cpp less more
<
None //===-- MBlazeISelLowering.cpp - MBlaze DAG Lowering Implementation -------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the interfaces that MBlaze uses to lower LLVM code into a
10 // selection DAG.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "mblaze-lower"
15 #include "MBlazeISelLowering.h"
16 #include "MBlazeMachineFunction.h"
17 #include "MBlazeSubtarget.h"
18 #include "MBlazeTargetMachine.h"
19 #include "MBlazeTargetObjectFile.h"
20 #include "llvm/CodeGen/CallingConvLower.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/MachineInstrBuilder.h"
24 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 #include "llvm/CodeGen/SelectionDAGISel.h"
26 #include "llvm/CodeGen/ValueTypes.h"
27 #include "llvm/IR/CallingConv.h"
28 #include "llvm/IR/DerivedTypes.h"
29 #include "llvm/IR/Function.h"
30 #include "llvm/IR/GlobalVariable.h"
31 #include "llvm/IR/Intrinsics.h"
32 #include "llvm/Support/Debug.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/raw_ostream.h"
35 using namespace llvm;
36
37 static bool CC_MBlaze_AssignReg(unsigned &ValNo, MVT &ValVT, MVT &LocVT,
38 CCValAssign::LocInfo &LocInfo,
39 ISD::ArgFlagsTy &ArgFlags,
40 CCState &State);
41
42 const char *MBlazeTargetLowering::getTargetNodeName(unsigned Opcode) const {
43 switch (Opcode) {
44 case MBlazeISD::JmpLink : return "MBlazeISD::JmpLink";
45 case MBlazeISD::GPRel : return "MBlazeISD::GPRel";
46 case MBlazeISD::Wrap : return "MBlazeISD::Wrap";
47 case MBlazeISD::ICmp : return "MBlazeISD::ICmp";
48 case MBlazeISD::Ret : return "MBlazeISD::Ret";
49 case MBlazeISD::Select_CC : return "MBlazeISD::Select_CC";
50 default : return NULL;
51 }
52 }
53
54 MBlazeTargetLowering::MBlazeTargetLowering(MBlazeTargetMachine &TM)
55 : TargetLowering(TM, new MBlazeTargetObjectFile()) {
56 Subtarget = &TM.getSubtarget();
57
58 // MBlaze does not have i1 type, so use i32 for
59 // setcc operations results (slt, sgt, ...).
60 setBooleanContents(ZeroOrOneBooleanContent);
61 setBooleanVectorContents(ZeroOrOneBooleanContent); // FIXME: Is this correct?
62
63 // Set up the register classes
64 addRegisterClass(MVT::i32, &MBlaze::GPRRegClass);
65 if (Subtarget->hasFPU()) {
66 addRegisterClass(MVT::f32, &MBlaze::GPRRegClass);
67 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
68 }
69
70 // Floating point operations which are not supported
71 setOperationAction(ISD::FREM, MVT::f32, Expand);
72 setOperationAction(ISD::FMA, MVT::f32, Expand);
73