llvm.org GIT mirror llvm / a70f28c
Adding the MicroBlaze backend. The MicroBlaze is a highly configurable 32-bit soft-microprocessor for use on Xilinx FPGAs. For more information see: http://www.xilinx.com/tools/microblaze.htm http://en.wikipedia.org/wiki/MicroBlaze The current LLVM MicroBlaze backend generates assembly which can be compiled using the an appropriate binutils assembler. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96969 91177308-0d34-0410-b5e6-96231b3b80d8 Wesley Peck 9 years ago
56 changed file(s) with 6736 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
334334 N: Bob Wilson
335335 E: bob.wilson@acm.org
336336 D: Advanced SIMD (NEON) support in the ARM backend
337
338 N: Wesley Peck
339 E: peckw@wesleypeck.com
340 W: http://wesleypeck.com/
341 D: MicroBlaze backend
290290 msp430-*) llvm_cv_target_arch="MSP430" ;;
291291 s390x-*) llvm_cv_target_arch="SystemZ" ;;
292292 bfin-*) llvm_cv_target_arch="Blackfin" ;;
293 mblaze-*) llvm_cv_target_arch="MBlaze" ;;
293294 *) llvm_cv_target_arch="Unknown" ;;
294295 esac])
295296
426427 MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
427428 SystemZ) AC_SUBST(TARGET_HAS_JIT,0) ;;
428429 Blackfin) AC_SUBST(TARGET_HAS_JIT,0) ;;
430 MBlaze) AC_SUBST(TARGET_HAS_JIT,0) ;;
429431 *) AC_SUBST(TARGET_HAS_JIT,0) ;;
430432 esac
431433 fi
492494 enableval=host
493495 fi
494496 case "$enableval" in
495 all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend" ;;
497 all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;;
496498 *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
497499 case "$a_target" in
498500 x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
511513 cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
512514 msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;;
513515 cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
516 mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
514517 host) case "$llvm_cv_target_arch" in
515518 x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
516519 x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
519522 Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
520523 ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
521524 Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
525 MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
522526 CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
523527 PIC16) TARGETS_TO_BUILD="PIC16 $TARGETS_TO_BUILD" ;;
524528 XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
23292329 msp430-*) llvm_cv_target_arch="MSP430" ;;
23302330 s390x-*) llvm_cv_target_arch="SystemZ" ;;
23312331 bfin-*) llvm_cv_target_arch="Blackfin" ;;
2332 microblaze-*) llvm_cv_target_arch="MBlaze" ;;
23322333 *) llvm_cv_target_arch="Unknown" ;;
23332334 esac
23342335 fi
47944795 ;;
47954796 Blackfin) TARGET_HAS_JIT=0
47964797 ;;
4798 MBlaze) TARGET_HAS_JIT=0
4799 ;;
47974800 *) TARGET_HAS_JIT=0
47984801 ;;
47994802 esac
48974900 enableval=host
48984901 fi
48994902 case "$enableval" in
4900 all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend" ;;
4903 all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ Blackfin CBackend MSIL CppBackend MBlaze" ;;
49014904 *)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
49024905 case "$a_target" in
49034906 x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
49164919 cbe) TARGETS_TO_BUILD="CBackend $TARGETS_TO_BUILD" ;;
49174920 msil) TARGETS_TO_BUILD="MSIL $TARGETS_TO_BUILD" ;;
49184921 cpp) TARGETS_TO_BUILD="CppBackend $TARGETS_TO_BUILD" ;;
4922 mblaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
49194923 host) case "$llvm_cv_target_arch" in
49204924 x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
49214925 x86_64) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
49244928 Alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
49254929 ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
49264930 Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
4931 MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
49274932 CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
49284933 PIC16) TARGETS_TO_BUILD="PIC16 $TARGETS_TO_BUILD" ;;
49294934 XCore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
7272 x86, // X86: i[3-9]86
7373 x86_64, // X86-64: amd64, x86_64
7474 xcore, // XCore: xcore
75 mblaze, // MBlaze: mblaze
7576
7677 InvalidArch
7778 };
3939 case x86: return "i386";
4040 case x86_64: return "x86_64";
4141 case xcore: return "xcore";
42 case mblaze: return "mblaze";
4243 }
4344
4445 return "";
6061
6162 case ppc64:
6263 case ppc: return "ppc";
64
65 case mblaze: return "mblaze";
6366
6467 case sparcv9:
6568 case sparc: return "sparc";
126129 return ppc64;
127130 if (Name == "ppc")
128131 return ppc;
132 if (Name == "mblaze")
133 return mblaze;
129134 if (Name == "sparc")
130135 return sparc;
131136 if (Name == "sparcv9")
197202 return "ppc";
198203 if (Str == "powerpc64")
199204 return "ppc64";
205 if (Str == "mblaze" || Str == "microblaze")
206 return "mblaze";
200207 if (Str == "arm")
201208 return "arm";
202209 if (Str == "armv4t" || Str == "thumbv4t")
233240 Arch = ppc;
234241 else if ((ArchName == "powerpc64") || (ArchName == "ppu"))
235242 Arch = ppc64;
243 else if (ArchName == "mblaze")
244 Arch = mblaze;
236245 else if (ArchName == "arm" ||
237246 ArchName.startswith("armv") ||
238247 ArchName == "xscale")
0 include_directories(
1 ${CMAKE_CURRENT_BINARY_DIR}/..
2 ${CMAKE_CURRENT_SOURCE_DIR}/..
3 )
4
5 add_llvm_library(LLVMMBlazeAsmPrinter
6 MBlazeAsmPrinter.cpp
7 )
8 add_dependencies(LLVMMBlazeAsmPrinter MBlazeCodeGenTable_gen)
0 //===-- 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 "MBlazeSubtarget.h"
18 #include "MBlazeInstrInfo.h"
19 #include "MBlazeTargetMachine.h"
20 #include "MBlazeMachineFunction.h"
21 #include "llvm/Constants.h"
22 #include "llvm/DerivedTypes.h"
23 #include "llvm/Module.h"
24 #include "llvm/CodeGen/AsmPrinter.h"
25 #include "llvm/CodeGen/DwarfWriter.h"
26 #include "llvm/CodeGen/MachineFunctionPass.h"
27 #include "llvm/CodeGen/MachineConstantPool.h"
28 #include "llvm/CodeGen/MachineFrameInfo.h"
29 #include "llvm/CodeGen/MachineInstr.h"
30 #include "llvm/MC/MCStreamer.h"
31 #include "llvm/MC/MCAsmInfo.h"
32 #include "llvm/MC/MCSymbol.h"
33 #include "llvm/Target/TargetData.h"
34 #include "llvm/Target/TargetLoweringObjectFile.h"
35 #include "llvm/Target/TargetMachine.h"
36 #include "llvm/Target/TargetOptions.h"
37 #include "llvm/Target/TargetRegistry.h"
38 #include "llvm/Support/ErrorHandling.h"
39 #include "llvm/ADT/Statistic.h"
40 #include "llvm/ADT/StringExtras.h"
41 #include "llvm/Support/Debug.h"
42 #include "llvm/Support/CommandLine.h"
43 #include "llvm/Support/FormattedStream.h"
44 #include "llvm/Support/MathExtras.h"
45 #include
46
47 using namespace llvm;
48
49 namespace {
50 class MBlazeAsmPrinter : public AsmPrinter {
51 const MBlazeSubtarget *Subtarget;
52 public:
53 explicit MBlazeAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
54 MCContext &Ctx, MCStreamer &Streamer,
55 const MCAsmInfo *T )
56 : AsmPrinter(O, TM, Ctx, Streamer, T) {
57 Subtarget = &TM.getSubtarget();
58 }
59
60 virtual const char *getPassName() const {
61 return "MBlaze Assembly Printer";
62 }
63
64 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
65 unsigned AsmVariant, const char *ExtraCode);
66 void printOperand(const MachineInstr *MI, int opNum);
67 void printUnsignedImm(const MachineInstr *MI, int opNum);
68 void printFSLImm(const MachineInstr *MI, int opNum);
69 void printMemOperand(const MachineInstr *MI, int opNum,
70 const char *Modifier = 0);
71 void printFCCOperand(const MachineInstr *MI, int opNum,
72 const char *Modifier = 0);
73 void printSavedRegsBitmask();
74 void printHex32(unsigned int Value);
75
76 const char *emitCurrentABIString();
77 void emitFrameDirective();
78
79 void printInstruction(const MachineInstr *MI); // autogenerated.
80 void EmitInstruction(const MachineInstr *MI) {
81 printInstruction(MI);
82 O << '\n';
83 }
84 virtual void EmitFunctionBodyStart();
85 virtual void EmitFunctionBodyEnd();
86 static const char *getRegisterName(unsigned RegNo);
87
88 virtual void EmitFunctionEntryLabel();
89 void EmitStartOfAsmFile(Module &M);
90 };
91 } // end of anonymous namespace
92
93 #include "MBlazeGenAsmWriter.inc"
94
95 //===----------------------------------------------------------------------===//
96 //
97 // MBlaze Asm Directives
98 //
99 // -- Frame directive "frame Stackpointer, Stacksize, RARegister"
100 // Describe the stack frame.
101 //
102 // -- Mask directives "mask bitmask, offset"
103 // Tells the assembler which registers are saved and where.
104 // bitmask - contain a little endian bitset indicating which registers are
105 // saved on function prologue (e.g. with a 0x80000000 mask, the
106 // assembler knows the register 31 (RA) is saved at prologue.
107 // offset - the position before stack pointer subtraction indicating where
108 // the first saved register on prologue is located. (e.g. with a
109 //
110 // Consider the following function prologue:
111 //
112 // .frame R19,48,R15
113 // .mask 0xc0000000,-8
114 // addiu R1, R1, -48
115 // sw R15, 40(R1)
116 // sw R19, 36(R1)
117 //
118 // With a 0xc0000000 mask, the assembler knows the register 15 (R15) and
119 // 19 (R19) are saved at prologue. As the save order on prologue is from
120 // left to right, R15 is saved first. A -8 offset means that after the
121 // stack pointer subtration, the first register in the mask (R15) will be
122 // saved at address 48-8=40.
123 //
124 //===----------------------------------------------------------------------===//
125
126 //===----------------------------------------------------------------------===//
127 // Mask directives
128 //===----------------------------------------------------------------------===//
129
130 // Create a bitmask with all callee saved registers for CPU or Floating Point
131 // registers. For CPU registers consider RA, GP and FP for saving if necessary.
132 void MBlazeAsmPrinter::printSavedRegsBitmask() {
133 const TargetRegisterInfo &RI = *TM.getRegisterInfo();
134 const MBlazeFunctionInfo *MBlazeFI = MF->getInfo();
135
136 // CPU Saved Registers Bitmasks
137 unsigned int CPUBitmask = 0;
138
139 // Set the CPU Bitmasks
140 const MachineFrameInfo *MFI = MF->getFrameInfo();
141 const std::vector &CSI = MFI->getCalleeSavedInfo();
142 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
143 unsigned RegNum = MBlazeRegisterInfo::getRegisterNumbering(CSI[i].getReg());
144 if (CSI[i].getRegClass() == MBlaze::CPURegsRegisterClass)
145 CPUBitmask |= (1 << RegNum);
146 }
147
148 // Return Address and Frame registers must also be set in CPUBitmask.
149 if (RI.hasFP(*MF))
150 CPUBitmask |= (1 << MBlazeRegisterInfo::
151 getRegisterNumbering(RI.getFrameRegister(*MF)));
152
153 if (MFI->hasCalls())
154 CPUBitmask |= (1 << MBlazeRegisterInfo::
155 getRegisterNumbering(RI.getRARegister()));
156
157 // Print CPUBitmask
158 O << "\t.mask \t"; printHex32(CPUBitmask); O << ','
159 << MBlazeFI->getCPUTopSavedRegOff() << '\n';
160 }
161
162 // Print a 32 bit hex number with all numbers.
163 void MBlazeAsmPrinter::printHex32(unsigned int Value) {
164 O << "0x";
165 for (int i = 7; i >= 0; i--)
166 O << utohexstr( (Value & (0xF << (i*4))) >> (i*4) );
167 }
168
169 //===----------------------------------------------------------------------===//
170 // Frame and Set directives
171 //===----------------------------------------------------------------------===//
172
173 /// Frame Directive
174 void MBlazeAsmPrinter::emitFrameDirective() {
175 const TargetRegisterInfo &RI = *TM.getRegisterInfo();
176
177 unsigned stackReg = RI.getFrameRegister(*MF);
178 unsigned returnReg = RI.getRARegister();
179 unsigned stackSize = MF->getFrameInfo()->getStackSize();
180
181
182 O << "\t.frame\t" << getRegisterName(stackReg)
183 << ',' << stackSize << ','
184 << getRegisterName(returnReg)
185 << '\n';
186 }
187
188 void MBlazeAsmPrinter::EmitFunctionEntryLabel() {
189 O << "\t.ent\t" << *CurrentFnSym << '\n';
190 OutStreamer.EmitLabel(CurrentFnSym);
191 }
192
193 /// EmitFunctionBodyStart - Targets can override this to emit stuff before
194 /// the first basic block in the function.
195 void MBlazeAsmPrinter::EmitFunctionBodyStart() {
196 emitFrameDirective();
197 printSavedRegsBitmask();
198 }
199
200 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
201 /// the last basic block in the function.
202 void MBlazeAsmPrinter::EmitFunctionBodyEnd() {
203 O << "\t.end\t" << *CurrentFnSym << '\n';
204 }
205
206 // Print out an operand for an inline asm expression.
207 bool MBlazeAsmPrinter::
208 PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
209 unsigned AsmVariant,const char *ExtraCode){
210 // Does this asm operand have a single letter operand modifier?
211 if (ExtraCode && ExtraCode[0])
212 return true; // Unknown modifier.
213
214 printOperand(MI, OpNo);
215 return false;
216 }
217
218 void MBlazeAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
219 const MachineOperand &MO = MI->getOperand(opNum);
220
221 switch (MO.getType()) {
222 case MachineOperand::MO_Register:
223 O << getRegisterName(MO.getReg());
224 break;
225
226 case MachineOperand::MO_Immediate:
227 O << (int)MO.getImm();
228 break;
229
230 case MachineOperand::MO_FPImmediate: {
231 const ConstantFP* fp = MO.getFPImm();
232 printHex32(fp->getValueAPF().bitcastToAPInt().getZExtValue());
233 O << ";\t# immediate = " << *fp;
234 break;
235 }
236
237 case MachineOperand::MO_MachineBasicBlock:
238 O << *MO.getMBB()->getSymbol(OutContext);
239 return;
240
241 case MachineOperand::MO_GlobalAddress:
242 O << *GetGlobalValueSymbol(MO.getGlobal());
243 break;
244
245 case MachineOperand::MO_ExternalSymbol:
246 O << *GetExternalSymbolSymbol(MO.getSymbolName());
247 break;
248
249 case MachineOperand::MO_JumpTableIndex:
250 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
251 << '_' << MO.getIndex();
252 break;
253
254 case MachineOperand::MO_ConstantPoolIndex:
255 O << MAI->getPrivateGlobalPrefix() << "CPI"
256 << getFunctionNumber() << "_" << MO.getIndex();
257 if (MO.getOffset())
258 O << "+" << MO.getOffset();
259 break;
260
261 default:
262 llvm_unreachable("");
263 }
264 }
265
266 void MBlazeAsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum) {
267 const MachineOperand &MO = MI->getOperand(opNum);
268 if (MO.getType() == MachineOperand::MO_Immediate)
269 O << (unsigned int)MO.getImm();
270 else
271 printOperand(MI, opNum);
272 }
273
274 void MBlazeAsmPrinter::printFSLImm(const MachineInstr *MI, int opNum) {
275 const MachineOperand &MO = MI->getOperand(opNum);
276 if (MO.getType() == MachineOperand::MO_Immediate)
277 O << "rfsl" << (unsigned int)MO.getImm();
278 else
279 printOperand(MI, opNum);
280 }
281
282 void MBlazeAsmPrinter::
283 printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier) {
284 printOperand(MI, opNum+1);
285 O << ", ";
286 printOperand(MI, opNum);
287 }
288
289 void MBlazeAsmPrinter::
290 printFCCOperand(const MachineInstr *MI, int opNum, const char *Modifier) {
291 const MachineOperand& MO = MI->getOperand(opNum);
292 O << MBlaze::MBlazeFCCToString((MBlaze::CondCode)MO.getImm());
293 }
294
295 void MBlazeAsmPrinter::EmitStartOfAsmFile(Module &M) {
296 }
297
298 // Force static initialization.
299 extern "C" void LLVMInitializeMBlazeAsmPrinter() {
300 RegisterAsmPrinter X(TheMBlazeTarget);
301 }
0 ##===- 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
9 LEVEL = ../../../..
10 LIBRARYNAME = LLVMMBlazeAsmPrinter
11
12 # Hack: we need to include 'main' MBlaze target directory to grab
13 # private headers
14 CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
15
16 include $(LEVEL)/Makefile.common
0 set(LLVM_TARGET_DEFINITIONS MBlaze.td)
1
2 tablegen(MBlazeGenRegisterInfo.h.inc -gen-register-desc-header)
3 tablegen(MBlazeGenRegisterNames.inc -gen-register-enums)
4 tablegen(MBlazeGenRegisterInfo.inc -gen-register-desc)
5 tablegen(MBlazeGenInstrNames.inc -gen-instr-enums)
6 tablegen(MBlazeGenInstrInfo.inc -gen-instr-desc)
7 tablegen(MBlazeGenAsmWriter.inc -gen-asm-writer)
8 tablegen(MBlazeGenDAGISel.inc -gen-dag-isel)
9 tablegen(MBlazeGenCallingConv.inc -gen-callingconv)
10 tablegen(MBlazeGenSubtarget.inc -gen-subtarget)
11 tablegen(MBlazeGenIntrinsics.inc -gen-tgt-intrinsic)
12
13 add_llvm_target(MBlazeCodeGen
14 MBlazeDelaySlotFiller.cpp
15 MBlazeInstrInfo.cpp
16 MBlazeISelDAGToDAG.cpp
17 MBlazeISelLowering.cpp
18 MBlazeMCAsmInfo.cpp
19 MBlazeRegisterInfo.cpp
20 MBlazeSubtarget.cpp
21 MBlazeTargetMachine.cpp
22 MBlazeTargetObjectFile.cpp
23 MBlazeIntrinsicInfo.cpp
24 )
25
26 target_link_libraries (LLVMMBlazeCodeGen LLVMSelectionDAG)
0 //===-- 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 "llvm/Target/TargetMachine.h"
18
19 namespace llvm {
20 class MBlazeTargetMachine;
21 class FunctionPass;
22 class MachineCodeEmitter;
23 class formatted_raw_ostream;
24
25 FunctionPass *createMBlazeISelDag(MBlazeTargetMachine &TM);
26 FunctionPass *createMBlazeDelaySlotFillerPass(MBlazeTargetMachine &TM);
27
28 extern Target TheMBlazeTarget;
29 } // end namespace llvm;
30
31 // Defines symbolic names for MBlaze registers. This defines a mapping from
32 // register name to register number.
33 #include "MBlazeGenRegisterNames.inc"
34
35 // Defines symbolic names for the MBlaze instructions.
36 #include "MBlazeGenInstrNames.inc"
37
38 #endif
0 //===- MBlaze.td - Describe the MBlaze Target Machine -----------*- 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 // 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 let TSFlagsFields = [];
29 let TSFlagsShifts = [];
30 }
31
32
33 //===----------------------------------------------------------------------===//
34 // Microblaze Subtarget features //
35 //===----------------------------------------------------------------------===//
36
37 def FeaturePipe3 : SubtargetFeature<"pipe3", "HasPipe3", "true",
38 "Implements 3-stage pipeline.">;
39 def FeatureBarrel : SubtargetFeature<"barrel", "HasBarrel", "true",
40 "Implements barrel shifter.">;
41 def FeatureDiv : SubtargetFeature<"div", "HasDiv", "true",
42 "Implements hardware divider.">;
43 def FeatureMul : SubtargetFeature<"mul", "HasMul", "true",
44 "Implements hardware multiplier.">;
45 def FeatureFSL : SubtargetFeature<"fsl", "HasFSL", "true",
46 "Implements FSL instructions.">;
47 def FeatureEFSL : SubtargetFeature<"efsl", "HasEFSL", "true",
48 "Implements extended FSL instructions.">;
49 def FeatureMSRSet : SubtargetFeature<"msrset", "HasMSRSet", "true",
50 "Implements MSR register set and clear.">;
51 def FeatureException : SubtargetFeature<"exception", "HasException", "true",
52 "Implements hardware exception support.">;
53 def FeaturePatCmp : SubtargetFeature<"patcmp", "HasPatCmp", "true",
54 "Implements pattern compare instruction.">;
55 def FeatureFPU : SubtargetFeature<"fpu", "HasFPU", "true",
56 "Implements floating point unit.">;
57 def FeatureESR : SubtargetFeature<"esr", "HasESR", "true",
58 "Implements ESR and EAR registers">;
59 def FeaturePVR : SubtargetFeature<"pvr", "HasPVR", "true",
60 "Implements processor version register.">;
61 def FeatureMul64 : SubtargetFeature<"mul64", "HasMul64", "true",
62 "Implements multiplier with 64-bit result">;
63 def FeatureSqrt : SubtargetFeature<"sqrt", "HasSqrt", "true",
64 "Implements sqrt and floating point convert.">;
65 def FeatureMMU : SubtargetFeature<"mmu", "HasMMU", "true",
66 "Implements memory management unit.">;
67
68 //===----------------------------------------------------------------------===//
69 // MBlaze processors supported.
70 //===----------------------------------------------------------------------===//
71
72 class Proc Features>
73 : Processor;
74
75
76 def : Proc<"v400", []>;
77 def : Proc<"v500", []>;
78 def : Proc<"v600", []>;
79 def : Proc<"v700", []>;
80 def : Proc<"v710", []>;
81
82 def MBlaze : Target {
83 let InstructionSet = MBlazeInstrInfo;
84 }
0 //===- MBlazeCallingConv.td - Calling Conventions 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 // This describes the calling conventions for MBlaze architecture.
9 //===----------------------------------------------------------------------===//
10
11 /// CCIfSubtarget - Match if the current subtarget has a feature F.
12 class CCIfSubtarget:
13 CCIf().", F), A>;
14
15 //===----------------------------------------------------------------------===//
16 // MBlaze ABI Calling Convention
17 //===----------------------------------------------------------------------===//
18
19 def CC_MBlaze : CallingConv<[
20 // Promote i8/i16 arguments to i32.
21 CCIfType<[i8, i16], CCPromoteToType>,
22
23 // Integer arguments are passed in integer registers.
24 CCIfType<[i32], CCAssignToReg<[R5, R6, R7, R8, R9, R10]>>,
25
26 // Single fp arguments are passed in floating point registers
27 CCIfType<[f32], CCAssignToReg<[F5, F6, F7, F8, F9, F10]>>,
28
29 // 32-bit values get stored in stack slots that are 4 bytes in
30 // size and 4-byte aligned.
31 CCIfType<[i32, f32], CCAssignToStack<4, 4>>
32 ]>;
33
34 def RetCC_MBlaze : CallingConv<[
35 // i32 are returned in registers R3, R4
36 CCIfType<[i32], CCAssignToReg<[R3, R4]>>,
37
38 // f32 are returned in registers F3, F4
39 CCIfType<[f32], CCAssignToReg<[F3, F4]>>
40 ]>;
0 //===-- 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 // Simple pass to fills delay slots with NOPs.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #define DEBUG_TYPE "delay-slot-filler"
14
15 #include "MBlaze.h"
16 #include "MBlazeTargetMachine.h"
17 #include "llvm/CodeGen/MachineFunctionPass.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/Target/TargetInstrInfo.h"
20 #include "llvm/ADT/Statistic.h"
21
22 using namespace llvm;
23
24 STATISTIC(FilledSlots, "Number of delay slots filled");
25
26 namespace {
27 struct Filler : public MachineFunctionPass {
28
29 TargetMachine &TM;
30 const TargetInstrInfo *TII;
31
32 static char ID;
33 Filler(TargetMachine &tm)
34 : MachineFunctionPass(&ID), TM(tm), TII(tm.getInstrInfo()) { }
35
36 virtual const char *getPassName() const {
37 return "MBlaze Delay Slot Filler";
38 }
39
40 bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
41 bool runOnMachineFunction(MachineFunction &F) {
42 bool Changed = false;
43 for (MachineFunction::iterator FI = F.begin(), FE = F.end();
44 FI != FE; ++FI)
45 Changed |= runOnMachineBasicBlock(*FI);
46 return Changed;
47 }
48
49 };
50 char Filler::ID = 0;
51 } // end of anonymous namespace
52
53 /// runOnMachineBasicBlock - Fill in delay slots for the given basic block.
54 /// Currently, we fill delay slots with NOPs. We assume there is only one
55 /// delay slot per delayed instruction.
56 bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
57 bool Changed = false;
58 for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I)
59 if (I->getDesc().hasDelaySlot()) {
60 MachineBasicBlock::iterator J = I;
61 ++J;
62 BuildMI(MBB, J, I->getDebugLoc(), TII->get(MBlaze::NOP));
63 ++FilledSlots;
64 Changed = true;
65 }
66 return Changed;
67 }
68
69 /// createMBlazeDelaySlotFillerPass - Returns a pass that fills in delay
70 /// slots in MBlaze MachineFunctions
71 FunctionPass *llvm::createMBlazeDelaySlotFillerPass(MBlazeTargetMachine &tm) {
72 return new Filler(tm);
73 }
74
0 //===-- 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 "MBlazeISelLowering.h"
16 #include "MBlazeMachineFunction.h"
17 #include "MBlazeRegisterInfo.h"
18 #include "MBlazeSubtarget.h"
19 #include "MBlazeTargetMachine.h"
20 #include "llvm/GlobalValue.h"
21 #include "llvm/Instructions.h"
22 #include "llvm/Intrinsics.h"
23 #include "llvm/Support/CFG.h"
24 #include "llvm/Type.h"
25 #include "llvm/CodeGen/MachineConstantPool.h"
26 #include "llvm/CodeGen/MachineFunction.h"
27 #include "llvm/CodeGen/MachineFrameInfo.h"
28 #include "llvm/CodeGen/MachineInstrBuilder.h"
29 #include "llvm/CodeGen/MachineRegisterInfo.h"
30 #include "llvm/CodeGen/SelectionDAGISel.h"
31 #include "llvm/Target/TargetMachine.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 //===----------------------------------------------------------------------===//
38 // Instruction Selector Implementation
39 //===----------------------------------------------------------------------===//
40
41 //===----------------------------------------------------------------------===//
42 // MBlazeDAGToDAGISel - MBlaze specific code to select MBlaze machine
43 // instructions for SelectionDAG operations.
44 //===----------------------------------------------------------------------===//
45 namespace {
46
47 class MBlazeDAGToDAGISel : public SelectionDAGISel {
48
49 /// TM - Keep a reference to MBlazeTargetMachine.
50 MBlazeTargetMachine &TM;
51
52 /// Subtarget - Keep a pointer to the MBlazeSubtarget around so that we can
53 /// make the right decision when generating code for different targets.
54 const MBlazeSubtarget &Subtarget;
55
56 public:
57 explicit MBlazeDAGToDAGISel(MBlazeTargetMachine &tm) :
58 SelectionDAGISel(tm),
59 TM(tm), Subtarget(tm.getSubtarget()) {}
60
61 virtual void InstructionSelect();
62
63 // Pass Name
64 virtual const char *getPassName() const {
65 return "MBlaze DAG->DAG Pattern Instruction Selection";
66 }
67 private:
68 // Include the pieces autogenerated from the target description.
69 #include "MBlazeGenDAGISel.inc"
70
71 /// getTargetMachine - Return a reference to the TargetMachine, casted
72 /// to the target-specific type.
73 const MBlazeTargetMachine &getTargetMachine() {
74 return static_cast(TM);
75 }
76
77 /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
78 /// to the target-specific type.
79 const MBlazeInstrInfo *getInstrInfo() {
80 return getTargetMachine().getInstrInfo();
81 }
82
83 SDNode *getGlobalBaseReg();
84 SDNode *Select(SDNode *N);
85
86 // Complex Pattern.
87 bool SelectAddr(SDNode *Op, SDValue N,
88 SDValue &Base, SDValue &Offset);
89
90 // Address Selection
91 bool SelectAddrRegReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index);
92 bool SelectAddrRegImm(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base);
93
94 // getI32Imm - Return a target constant with the specified value, of type i32.
95 inline SDValue getI32Imm(unsigned Imm) {
96 return CurDAG->getTargetConstant(Imm, MVT::i32);
97 }
98
99
100 #ifndef NDEBUG
101 unsigned Indent;
102 #endif
103 };
104
105 }
106
107 /// isIntS32Immediate - This method tests to see if the node is either a 32-bit
108 /// or 64-bit immediate, and if the value can be accurately represented as a
109 /// sign extension from a 32-bit value. If so, this returns true and the
110 /// immediate.
111 static bool isIntS32Immediate(SDNode *N, int32_t &Imm) {
112 unsigned Opc = N->getOpcode();
113 if (Opc != ISD::Constant)
114 return false;
115
116 Imm = (int32_t)cast(N)->getZExtValue();
117 if (N->getValueType(0) == MVT::i32)
118 return Imm == (int32_t)cast(N)->getZExtValue();
119 else
120 return Imm == (int64_t)cast(N)->getZExtValue();
121 }
122
123 static bool isIntS32Immediate(SDValue Op, int32_t &Imm) {
124 return isIntS32Immediate(Op.getNode(), Imm);
125 }
126
127 /// InstructionSelect - This callback is invoked by
128 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
129 void MBlazeDAGToDAGISel::InstructionSelect() {
130 // Codegen the basic block.
131 DEBUG(errs() << "===== Instruction selection begins:\n");
132 DEBUG(Indent = 0);
133
134 // Select target instructions for the DAG.
135 SelectRoot(*CurDAG);
136
137 DEBUG(errs() << "===== Instruction selection ends:\n");
138
139 CurDAG->RemoveDeadNodes();
140 }
141
142 /// SelectAddressRegReg - Given the specified addressed, check to see if it
143 /// can be represented as an indexed [r+r] operation. Returns false if it
144 /// can be more efficiently represented with [r+imm].
145 bool MBlazeDAGToDAGISel::
146 SelectAddrRegReg(SDNode *Op, SDValue N, SDValue &Base, SDValue &Index) {
147 if (N.getOpcode() == ISD::FrameIndex) return false;
148 if (N.getOpcode() == ISD::TargetExternalSymbol ||
149 N.getOpcode() == ISD::TargetGlobalAddress)
150 return false; // direct calls.
151
152 if (N.getOperand(0).getOpcode() == ISD::TargetJumpTable ||
153 N.getOperand(1).getOpcode() == ISD::TargetJumpTable)
154 return false; // jump tables.
155
156 int32_t imm = 0;
157 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
158 if (isIntS32Immediate(N.getOperand(1), imm))
159 return false; // r+i
160
161 Base = N.getOperand(1);
162 Index = N.getOperand(0);
163 return true;
164 }
165
166 return false;
167 }
168
169 /// Returns true if the address N can be represented by a base register plus
170 /// a signed 32-bit displacement [r+imm], and if it is not better
171 /// represented as reg+reg.
172 bool MBlazeDAGToDAGISel::
173 SelectAddrRegImm(SDNode *Op, SDValue N, SDValue &Disp, SDValue &Base) {
174 // If this can be more profitably realized as r+r, fail.
175 if (SelectAddrRegReg(Op, N, Disp, Base))
176 return false;
177
178 if (N.getOpcode() == ISD::ADD || N.getOpcode() == ISD::OR) {
179 int32_t imm = 0;
180 if (isIntS32Immediate(N.getOperand(1), imm)) {
181 Disp = CurDAG->getTargetConstant(imm, MVT::i32);
182 if (FrameIndexSDNode *FI = dyn_cast(N.getOperand(0))) {
183 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType());
184 } else {
185 Base = N.getOperand(0);
186 }
187 DEBUG( errs() << "WESLEY: Using Operand Immediate\n" );
188 return true; // [r+i]
189 }
190 } else if (ConstantSDNode *CN = dyn_cast(N)) {
191 // Loading from a constant address.
192 uint32_t Imm = CN->getZExtValue();
193 Disp = CurDAG->getTargetConstant(Imm, CN->getValueType(0));
194 Base = CurDAG->getRegister(MBlaze::R0, CN->getValueType(0));
195 DEBUG( errs() << "WESLEY: Using Constant Node\n" );
196 return true;
197 }
198
199 Disp = CurDAG->getTargetConstant(0, TM.getTargetLowering()->getPointerTy());
200 if (FrameIndexSDNode *FI = dyn_cast(N))
201 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType());
202 else
203 Base = N;
204 return true; // [r+0]
205 }
206
207 /// getGlobalBaseReg - Output the instructions required to put the
208 /// GOT address into a register.
209 SDNode *MBlazeDAGToDAGISel::getGlobalBaseReg() {
210 unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
211 return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
212 }
213
214 /// ComplexPattern used on MBlazeInstrInfo
215 /// Used on MBlaze Load/Store instructions
216 bool MBlazeDAGToDAGISel::
217 SelectAddr(SDNode *Op, SDValue Addr, SDValue &Offset, SDValue &Base) {
218 // if Address is FI, get the TargetFrameIndex.
219 if (FrameIndexSDNode *FIN = dyn_cast(Addr)) {
220 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
221 Offset = CurDAG->getTargetConstant(0, MVT::i32);
222 return true;
223 }
224
225 // on PIC code Load GA
226 if (TM.getRelocationModel() == Reloc::PIC_) {
227 if ((Addr.getOpcode() == ISD::TargetGlobalAddress) ||
228 (Addr.getOpcode() == ISD::TargetConstantPool) ||
229 (Addr.getOpcode() == ISD::TargetJumpTable)){
230 Base = CurDAG->getRegister(MBlaze::R15, MVT::i32);
231 Offset = Addr;
232 return true;
233 }
234 } else {
235 if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
236 Addr.getOpcode() == ISD::TargetGlobalAddress))
237 return false;
238 }
239
240 // Operand is a result from an ADD.
241 if (Addr.getOpcode() == ISD::ADD) {
242 if (ConstantSDNode *CN = dyn_cast(Addr.getOperand(1))) {
243 if (Predicate_immSExt16(CN)) {
244
245 // If the first operand is a FI, get the TargetFI Node
246 if (FrameIndexSDNode *FIN = dyn_cast
247 (Addr.getOperand(0))) {
248 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
249 } else {
250 Base = Addr.getOperand(0);
251 }
252
253 Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
254 return true;
255 }
256 }
257 }
258
259 Base = Addr;
260 Offset = CurDAG->getTargetConstant(0, MVT::i32);
261 return true;
262 }
263
264 /// Select instructions not customized! Used for
265 /// expanded, promoted and normal instructions
266 SDNode* MBlazeDAGToDAGISel::Select(SDNode *Node) {
267 unsigned Opcode = Node->getOpcode();
268 DebugLoc dl = Node->getDebugLoc();
269
270 // Dump information about the Node being selected
271 DEBUG(errs().indent(Indent) << "Selecting: ";
272 Node->dump(CurDAG);
273 errs() << "\n");
274 DEBUG(Indent += 2);
275
276 // If we have a custom node, we already have selected!
277 if (Node->isMachineOpcode()) {
278 DEBUG(errs().indent(Indent-2) << "== ";
279 Node->dump(CurDAG);
280 errs() << "\n");
281 DEBUG(Indent -= 2);
282 return NULL;
283 }
284
285 ///
286 // Instruction Selection not handled by the auto-generated
287 // tablegen selection should be handled here.
288 ///
289 switch(Opcode) {
290 default: break;
291
292 // Get target GOT address.
293 case ISD::GLOBAL_OFFSET_TABLE:
294 return getGlobalBaseReg();
295
296 case ISD::FrameIndex: {
297 SDValue imm = CurDAG->getTargetConstant(0, MVT::i32);
298 int FI = dyn_cast(Node)->getIndex();
299 EVT VT = Node->getValueType(0);
300 SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
301 unsigned Opc = MBlaze::ADDI;
302 if (Node->hasOneUse())
303 return CurDAG->SelectNodeTo(Node, Opc, VT, TFI, imm);
304 return CurDAG->getMachineNode(Opc, dl, VT, TFI, imm);
305 }
306
307
308 /// Handle direct and indirect calls when using PIC. On PIC, when
309 /// GOT is smaller than about 64k (small code) the GA target is
310 /// loaded with only one instruction. Otherwise GA's target must
311 /// be loaded with 3 instructions.
312 case MBlazeISD::JmpLink: {
313 if (TM.getRelocationModel() == Reloc::PIC_) {
314 SDValue Chain = Node->getOperand(0);
315 SDValue Callee = Node->getOperand(1);
316 SDValue R20Reg = CurDAG->getRegister(MBlaze::R20, MVT::i32);
317 SDValue InFlag(0, 0);
318
319 if ( (isa(Callee)) ||
320 (isa(Callee)) )
321 {
322 /// Direct call for global addresses and external symbols
323 SDValue GPReg = CurDAG->getRegister(MBlaze::R15, MVT::i32);
324
325 // Use load to get GOT target
326 SDValue Ops[] = { Callee, GPReg, Chain };
327 SDValue Load = SDValue(CurDAG->getMachineNode(MBlaze::LW, dl,
328 MVT::i32, MVT::Other, Ops, 3), 0);
329 Chain = Load.getValue(1);
330
331 // Call target must be on T9
332 Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Load, InFlag);
333 } else
334 /// Indirect call
335 Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Callee, InFlag);
336
337 // Emit Jump and Link Register
338 SDNode *ResNode = CurDAG->getMachineNode(MBlaze::BRLID, dl, MVT::Other,
339 MVT::Flag, R20Reg, Chain);
340 Chain = SDValue(ResNode, 0);
341 InFlag = SDValue(ResNode, 1);
342 ReplaceUses(SDValue(Node, 0), Chain);
343 ReplaceUses(SDValue(Node, 1), InFlag);
344 return ResNode;
345 }
346 }
347 }
348
349 // Select the default instruction
350 SDNode *ResNode = SelectCode(Node);
351
352 DEBUG(errs().indent(Indent-2) << "=> ");
353 if (ResNode == NULL || ResNode == Node)
354 DEBUG(Node->dump(CurDAG));
355 else
356 DEBUG(ResNode->dump(CurDAG));
357 DEBUG(errs() << "\n");
358 DEBUG(Indent -= 2);
359
360 return ResNode;
361 }
362
363 /// createMBlazeISelDag - This pass converts a legalized DAG into a
364 /// MBlaze-specific DAG, ready for instruction scheduling.
365 FunctionPass *llvm::createMBlazeISelDag(MBlazeTargetMachine &TM) {
366 return new MBlazeDAGToDAGISel(TM);
367 }
0 //===-- 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 "MBlazeTargetMachine.h"
18 #include "MBlazeTargetObjectFile.h"
19 #include "MBlazeSubtarget.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/Function.h"
22 #include "llvm/GlobalVariable.h"
23 #include "llvm/Intrinsics.h"
24 #include "llvm/CallingConv.h"
25 #include "llvm/CodeGen/CallingConvLower.h"
26 #include "llvm/CodeGen/MachineFrameInfo.h"
27 #include "llvm/CodeGen/MachineFunction.h"
28 #include "llvm/CodeGen/MachineInstrBuilder.h"
29 #include "llvm/CodeGen/MachineRegisterInfo.h"
30 #include "llvm/CodeGen/SelectionDAGISel.h"
31 #include "llvm/CodeGen/ValueTypes.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 const char *MBlazeTargetLowering::getTargetNodeName(unsigned Opcode) const {
38 switch (Opcode) {
39 case MBlazeISD::JmpLink : return "MBlazeISD::JmpLink";
40 case MBlazeISD::GPRel : return "MBlazeISD::GPRel";
41 case MBlazeISD::Wrap : return "MBlazeISD::Wrap";
42 case MBlazeISD::ICmp : return "MBlazeISD::ICmp";
43 case MBlazeISD::Ret : return "MBlazeISD::Ret";
44 case MBlazeISD::Select_CC : return "MBlazeISD::Select_CC";
45 default : return NULL;
46 }
47 }
48
49 MBlazeTargetLowering::MBlazeTargetLowering(MBlazeTargetMachine &TM)
50 : TargetLowering(TM, new MBlazeTargetObjectFile()) {
51 Subtarget = &TM.getSubtarget();
52
53 // MBlaze does not have i1 type, so use i32 for
54 // setcc operations results (slt, sgt, ...).
55 setBooleanContents(ZeroOrOneBooleanContent);
56
57 // Set up the register classes
58 addRegisterClass(MVT::i32, MBlaze::CPURegsRegisterClass);
59 if (Subtarget->hasFPU()) {
60 addRegisterClass(MVT::f32, MBlaze::FGR32RegisterClass);
61 setOperationAction(ISD::ConstantFP, MVT::f32, Legal);
62 }
63
64 // Floating point operations which are not supported
65 setOperationAction(ISD::FREM, MVT::f32, Expand);
66 setOperationAction(ISD::UINT_TO_FP, MVT::i8, Expand);
67 setOperationAction(ISD::UINT_TO_FP, MVT::i16, Expand);
68 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
69 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
70 setOperationAction(ISD::FP_ROUND, MVT::f32, Expand);
71 setOperationAction(ISD::FP_ROUND, MVT::f64, Expand);
72 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
73 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
74 setOperationAction(ISD::FSIN, MVT::f32, Expand);
75 setOperationAction(ISD::FCOS, MVT::f32, Expand);
76 setOperationAction(ISD::FPOWI, MVT::f32, Expand);
77 setOperationAction(ISD::FPOW, MVT::f32, Expand);
78 setOperationAction(ISD::FLOG, MVT::f32, Expand);
79 setOperationAction(ISD::FLOG2, MVT::f32, Expand);
80 setOperationAction(ISD::FLOG10, MVT::f32, Expand);
81 setOperationAction(ISD::FEXP, MVT::f32, Expand);
82
83 // Load extented operations for i1 types must be promoted
84 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
85 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
86 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
87
88 // MBlaze has no REM or DIVREM operations.
89 setOperationAction(ISD::UREM, MVT::i32, Expand);
90 setOperationAction(ISD::SREM, MVT::i32, Expand);
91 setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
92 setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
93
94 // If the processor doesn't support multiply then expand it
95 if (!Subtarget->hasMul()) {
96 setOperationAction(ISD::MUL, MVT::i32, Expand);
97 }
98
99 // If the processor doesn't support 64-bit multiply then expand
100 if (!Subtarget->hasMul() || !Subtarget->hasMul64()) {
101 setOperationAction(ISD::MULHS, MVT::i32, Expand);
102 setOperationAction(ISD::MULHS, MVT::i64, Expand);
103 setOperationAction(ISD::MULHU, MVT::i32, Expand);
104 setOperationAction(ISD::MULHU, MVT::i64, Expand);
105 }
106
107 // If the processor doesn't support division then expand
108 if (!Subtarget->hasDiv()) {
109 setOperationAction(ISD::UDIV, MVT::i32, Expand);
110 setOperationAction(ISD::SDIV, MVT::i32, Expand);
111 }
112
113 // Expand unsupported conversions
114 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand);
115 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand);
116
117 // Expand SELECT_CC
118 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
119
120 // MBlaze doesn't have MUL_LOHI
121 setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
122 setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
123 setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
124 setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
125
126 // Used by legalize types to correctly generate the setcc result.
127 // Without this, every float setcc comes with a AND/OR with the result,
128 // we don't want this, since the fpcmp result goes to a flag register,
129 // which is used implicitly by brcond and select operations.
130 AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
131 AddPromotedToType(ISD::SELECT, MVT::i1, MVT::i32);
132 AddPromotedToType(ISD::SELECT_CC, MVT::i1, MVT::i32);
133
134 // MBlaze Custom Operations
135 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
136 setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
137 setOperationAction(ISD::JumpTable, MVT::i32, Custom);
138 setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
139
140 // Operations not directly supported by MBlaze.
141 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
142 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
143 setOperationAction(ISD::BR_CC, MVT::Other, Expand);
144 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
145 setOperationAction(ISD::ROTL, MVT::i32, Expand);
146 setOperationAction(ISD::ROTR, MVT::i32, Expand);
147 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
148 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
149 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
150 setOperationAction(ISD::CTLZ, MVT::i32, Expand);
151 setOperationAction(ISD::CTTZ, MVT::i32, Expand);
152 setOperationAction(ISD::CTPOP, MVT::i32, Expand);
153 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
154
155 // We don't have line number support yet.
156 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
157
158 // Use the default for now
159 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
160 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
161 setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
162
163 // MBlaze doesn't have extending float->double load/store
164 setLoadExtAction(ISD::EXTLOAD, MVT::f32, Expand);
165 setTruncStoreAction(MVT::f64, MVT::f32, Expand);
166
167 setStackPointerRegisterToSaveRestore(MBlaze::R1);
168 computeRegisterProperties();
169 }
170
171 MVT::SimpleValueType MBlazeTargetLowering::getSetCCResultType(EVT VT) const {
172 return MVT::i32;
173 }
174
175 /// getFunctionAlignment - Return the Log2 alignment of this function.
176 unsigned MBlazeTargetLowering::getFunctionAlignment(const Function *) const {
177 return 2;
178 }
179
180 SDValue MBlazeTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
181 switch (Op.getOpcode())
182 {
183 case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
184 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
185 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
186 case ISD::JumpTable: return LowerJumpTable(Op, DAG);
187 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
188 }
189 return SDValue();
190 }
191
192 //===----------------------------------------------------------------------===//
193 // Lower helper functions
194 //===----------------------------------------------------------------------===//
195 MachineBasicBlock* MBlazeTargetLowering::
196 EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB,
197 DenseMap
198 MachineBasicBlock*> *EM) const {
199 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
200 DebugLoc dl = MI->getDebugLoc();
201
202 switch (MI->getOpcode()) {
203 default: assert(false && "Unexpected instr type to insert");
204 case MBlaze::ShiftRL:
205 case MBlaze::ShiftRA:
206 case MBlaze::ShiftL: {
207 // To "insert" a shift left instruction, we actually have to insert a
208 // simple loop. The incoming instruction knows the destination vreg to
209 // set, the source vreg to operate over and the shift amount.
210 const BasicBlock *LLVM_BB = BB->getBasicBlock();
211 MachineFunction::iterator It = BB;
212 ++It;
213
214 // start:
215 // andi samt, samt, 31
216 // beqid samt, finish
217 // add dst, src, r0
218 // loop:
219 // addik samt, samt, -1
220 // sra dst, dst
221 // bneid samt, loop
222 // nop
223 // finish:
224 MachineFunction *F = BB->getParent();
225 MachineRegisterInfo &R = F->getRegInfo();
226 MachineBasicBlock *loop = F->CreateMachineBasicBlock(LLVM_BB);
227 MachineBasicBlock *finish = F->CreateMachineBasicBlock(LLVM_BB);
228
229 unsigned IAMT = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
230 BuildMI(BB, dl, TII->get(MBlaze::ANDI), IAMT)
231 .addReg(MI->getOperand(2).getReg())
232 .addImm(31);
233
234 unsigned IVAL = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
235 BuildMI(BB, dl, TII->get(MBlaze::ADDI), IVAL)
236 .addReg(MI->getOperand(1).getReg())
237 .addImm(0);
238
239 BuildMI(BB, dl, TII->get(MBlaze::BEQID))
240 .addReg(IAMT)
241 .addMBB(finish);
242
243 F->insert(It, loop);
244 F->insert(It, finish);
245
246 // Update machine-CFG edges by first adding all successors of the current
247 // block to the new block which will contain the Phi node for the select.
248 // Also inform sdisel of the edge changes.
249 for(MachineBasicBlock::succ_iterator i = BB->succ_begin(),
250 e = BB->succ_end(); i != e; ++i) {
251 EM->insert(std::make_pair(*i, finish));
252 finish->addSuccessor(*i);
253 }
254
255 // Next, remove all successors of the current block, and add the true
256 // and fallthrough blocks as its successors.
257 while(!BB->succ_empty())
258 BB->removeSuccessor(BB->succ_begin());
259 BB->addSuccessor(loop);
260 BB->addSuccessor(finish);
261
262 // Next, add the finish block as a successor of the loop block
263 loop->addSuccessor(finish);
264 loop->addSuccessor(loop);
265
266 unsigned DST = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
267 unsigned NDST = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
268 BuildMI(loop, dl, TII->get(MBlaze::PHI), DST)
269 .addReg(IVAL).addMBB(BB)
270 .addReg(NDST).addMBB(loop);
271
272 unsigned SAMT = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
273 unsigned NAMT = R.createVirtualRegister(MBlaze::CPURegsRegisterClass);
274 BuildMI(loop, dl, TII->get(MBlaze::PHI), SAMT)
275 .addReg(IAMT).addMBB(BB)
276 .addReg(NAMT).addMBB(loop);
277
278 if (MI->getOpcode() == MBlaze::ShiftL)
279 BuildMI(loop, dl, TII->get(MBlaze::ADD), NDST).addReg(DST).addReg(DST);
280 else if (MI->getOpcode() == MBlaze::ShiftRA)
281 BuildMI(loop, dl, TII->get(MBlaze::SRA), NDST).addReg(DST);
282 else if (MI->getOpcode() == MBlaze::ShiftRL)
283 BuildMI(loop, dl, TII->get(MBlaze::SRL), NDST).addReg(DST);
284 else
285 llvm_unreachable( "Cannot lower unknown shift instruction" );
286
287 BuildMI(loop, dl, TII->get(MBlaze::ADDI), NAMT)
288 .addReg(SAMT)
289 .addImm(-1);
290
291 BuildMI(loop, dl, TII->get(MBlaze::BNEID))
292 .addReg(NAMT)
293 .addMBB(loop);
294
295 BuildMI(finish, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg())
296 .addReg(IVAL).addMBB(BB)
297 .addReg(NDST).addMBB(loop);
298
299 // The pseudo instruction is no longer needed so remove it
300 F->DeleteMachineInstr(MI);
301 return finish;
302 }
303
304 case MBlaze::Select_FCC:
305 case MBlaze::Select_CC: {
306 // To "insert" a SELECT_CC instruction, we actually have to insert the
307 // diamond control-flow pattern. The incoming instruction knows the
308 // destination vreg to set, the condition code register to branch on, the
309 // true/false values to select between, and a branch opcode to use.
310 const BasicBlock *LLVM_BB = BB->getBasicBlock();
311 MachineFunction::iterator It = BB;
312 ++It;
313
314 // thisMBB:
315 // ...
316 // TrueVal = ...
317 // setcc r1, r2, r3
318 // bNE r1, r0, copy1MBB
319 // fallthrough --> copy0MBB
320 MachineFunction *F = BB->getParent();
321 MachineBasicBlock *flsBB = F->CreateMachineBasicBlock(LLVM_BB);
322 MachineBasicBlock *dneBB = F->CreateMachineBasicBlock(LLVM_BB);
323
324 unsigned Opc;
325 switch (MI->getOperand(4).getImm()) {
326 default: llvm_unreachable( "Unknown branch condition" );
327 case MBlazeCC::EQ: Opc = MBlaze::BNEID; break;
328 case MBlazeCC::NE: Opc = MBlaze::BEQID; break;
329 case MBlazeCC::GT: Opc = MBlaze::BLEID; break;
330 case MBlazeCC::LT: Opc = MBlaze::BGEID; break;
331 case MBlazeCC::GE: Opc = MBlaze::BLTID; break;
332 case MBlazeCC::LE: Opc = MBlaze::BGTID; break;
333 }
334
335 BuildMI(BB, dl, TII->get(Opc))
336 .addReg(MI->getOperand(3).getReg())
337 .addMBB(dneBB);
338
339 F->insert(It, flsBB);
340 F->insert(It, dneBB);
341
342 // Update machine-CFG edges by first adding all successors of the current
343 // block to the new block which will contain the Phi node for the select.
344 // Also inform sdisel of the edge changes.
345 for(MachineBasicBlock::succ_iterator i = BB->succ_begin(),
346 e = BB->succ_end(); i != e; ++i) {
347 EM->insert(std::make_pair(*i, dneBB));
348 dneBB->addSuccessor(*i);
349 }
350
351 // Next, remove all successors of the current block, and add the true
352 // and fallthrough blocks as its successors.
353 while(!BB->succ_empty())
354 BB->removeSuccessor(BB->succ_begin());
355 BB->addSuccessor(flsBB);
356 BB->addSuccessor(dneBB);
357 flsBB->addSuccessor(dneBB);
358
359 // sinkMBB:
360 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
361 // ...
362 //BuildMI(dneBB, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg())
363 // .addReg(MI->getOperand(1).getReg()).addMBB(flsBB)
364 // .addReg(MI->getOperand(2).getReg()).addMBB(BB);
365
366 BuildMI(dneBB, dl, TII->get(MBlaze::PHI), MI->getOperand(0).getReg())
367 .addReg(MI->getOperand(2).getReg()).addMBB(flsBB)
368 .addReg(MI->getOperand(1).getReg()).addMBB(BB);
369
370 F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
371 return dneBB;
372 }
373 }
374 }
375
376 //===----------------------------------------------------------------------===//
377 // Misc Lower Operation implementation
378 //===----------------------------------------------------------------------===//
379 //
380
381 SDValue MBlazeTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
382 SDValue LHS = Op.getOperand(0);
383 SDValue RHS = Op.getOperand(1);
384 SDValue TrueVal = Op.getOperand(2);
385 SDValue FalseVal = Op.getOperand(3);
386 DebugLoc dl = Op.getDebugLoc();
387 unsigned Opc;
388
389 SDValue CompareFlag;
390 if (LHS.getValueType() == MVT::i32) {
391 Opc = MBlazeISD::Select_CC;
392 CompareFlag = DAG.getNode(MBlazeISD::ICmp, dl, MVT::i32, LHS, RHS)
393 .getValue(1);
394 } else {
395 llvm_unreachable( "Cannot lower select_cc with unknown type" );
396 }
397
398 return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal,
399 CompareFlag);
400 }
401
402 SDValue MBlazeTargetLowering::
403 LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
404 // FIXME there isn't actually debug info here
405 DebugLoc dl = Op.getDebugLoc();
406 GlobalValue *GV = cast(Op)->getGlobal();
407 SDValue GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
408
409 return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, GA);
410 }
411
412 SDValue MBlazeTargetLowering::
413 LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) {
414 llvm_unreachable("TLS not implemented for MicroBlaze.");
415 return SDValue(); // Not reached
416 }
417
418 SDValue MBlazeTargetLowering::
419 LowerJumpTable(SDValue Op, SelectionDAG &DAG) {
420 SDValue ResNode;
421 SDValue HiPart;
422 // FIXME there isn't actually debug info here
423 DebugLoc dl = Op.getDebugLoc();
424 bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
425 unsigned char OpFlag = IsPIC ? MBlazeII::MO_GOT : MBlazeII::MO_ABS_HILO;
426
427 EVT PtrVT = Op.getValueType();
428 JumpTableSDNode *JT = cast(Op);
429
430 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, OpFlag);
431 return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, JTI);
432 //return JTI;
433 }
434
435 SDValue MBlazeTargetLowering::
436 LowerConstantPool(SDValue Op, SelectionDAG &DAG) {
437 SDValue ResNode;
438 EVT PtrVT = Op.getValueType();
439 ConstantPoolSDNode *N = cast(Op);
440 Constant *C = N->getConstVal();
441 SDValue Zero = DAG.getConstant(0, PtrVT);
442 // FIXME there isn't actually debug info here
443 DebugLoc dl = Op.getDebugLoc();
444
445 SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment(),
446 N->getOffset(), MBlazeII::MO_ABS_HILO);
447 return DAG.getNode(MBlazeISD::Wrap, dl, MVT::i32, CP);
448 }
449
450 //===----------------------------------------------------------------------===//
451 // Calling Convention Implementation
452 //===----------------------------------------------------------------------===//
453
454 #include "MBlazeGenCallingConv.inc"
455
456 //===----------------------------------------------------------------------===//
457 // Call Calling Convention Implementation
458 //===----------------------------------------------------------------------===//
459
460 /// LowerCall - functions arguments are copied from virtual regs to
461 /// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
462 /// TODO: isVarArg, isTailCall.
463 SDValue MBlazeTargetLowering::
464 LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
465 bool isVarArg, bool &isTailCall,
466 const SmallVectorImpl &Outs,
467 const SmallVectorImpl &Ins,
468 DebugLoc dl, SelectionDAG &DAG,
469 SmallVectorImpl &InVals) {
470 MachineFunction &MF = DAG.getMachineFunction();
471 MachineFrameInfo *MFI = MF.getFrameInfo();
472 bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
473
474 // Analyze operands of the call, assigning locations to each operand.
475 SmallVector ArgLocs;
476 CCState CCInfo(CallConv, isVarArg, getTargetMachine(), ArgLocs,
477 *DAG.getContext());
478 CCInfo.AnalyzeCallOperands(Outs, CC_MBlaze);
479
480 // Get a count of how many bytes are to be pushed on the stack.
481 unsigned NumBytes = CCInfo.getNextStackOffset();
482 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true));
483
484 SmallVector, 8> RegsToPass;
485 SmallVector MemOpChains;
486
487 // First/LastArgStackLoc contains the first/last
488 // "at stack" argument location.
489 int LastArgStackLoc = 0;
490 unsigned FirstStackArgLoc = 4;
491
492 // Walk the register/memloc assignments, inserting copies/loads.
493 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
494 CCValAssign &VA = ArgLocs[i];
495 EVT RegVT = VA.getLocVT();
496 SDValue Arg = Outs[i].Val;
497
498 // Promote the value if needed.
499 switch (VA.getLocInfo()) {
500 default: llvm_unreachable("Unknown loc info!");
501 case CCValAssign::Full: break;
502 case CCValAssign::SExt:
503 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, RegVT, Arg);
504 break;
505 case CCValAssign::ZExt:
506 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, RegVT, Arg);
507 break;
508 case CCValAssign::AExt:
509 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, RegVT, Arg);
510 break;
511 case CCValAssign::BCvt:
512 Arg = DAG.getNode(ISD::BIT_CONVERT, dl, RegVT, Arg);
513 break;
514 }
515
516 // Arguments that can be passed on register must be kept at
517 // RegsToPass vector
518 if (VA.isRegLoc()) {
519 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
520 } else {
521 // Register can't get to this point...
522 assert(VA.isMemLoc());
523
524 // Create the frame index object for this incoming parameter
525 LastArgStackLoc = (FirstStackArgLoc + VA.getLocMemOffset());
526 int FI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8,
527 LastArgStackLoc, true, false);
528
529 SDValue PtrOff = DAG.getFrameIndex(FI,getPointerTy());
530
531 // emit ISD::STORE whichs stores the
532 // parameter value to a stack Location
533 MemOpChains.push_back(DAG.getStore(Chain, dl, Arg, PtrOff, NULL, 0,
534 false, false, 0));
535 }
536 }
537
538 // Transform all store nodes into one single node because all store
539 // nodes are independent of each other.
540 if (!MemOpChains.empty())
541 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other,
542 &MemOpChains[0], MemOpChains.size());
543
544 // Build a sequence of copy-to-reg nodes chained together with token
545 // chain and flag operands which copy the outgoing args into registers.
546 // The InFlag in necessary since all emited instructions must be
547 // stuck together.
548 SDValue InFlag;
549 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
550 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
551 RegsToPass[i].second, InFlag);
552 InFlag = Chain.getValue(1);
553 }
554
555 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
556 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
557 // node so that legalize doesn't hack it.
558 unsigned char OpFlag = IsPIC ? MBlazeII::MO_GOT_CALL : MBlazeII::MO_NO_FLAG;
559 if (GlobalAddressSDNode *G = dyn_cast(Callee))
560 Callee = DAG.getTargetGlobalAddress(G->getGlobal(),
561 getPointerTy(), 0, OpFlag);
562 else if (ExternalSymbolSDNode *S = dyn_cast(Callee))
563 Callee = DAG.getTargetExternalSymbol(S->getSymbol(),
564 getPointerTy(), OpFlag);
565
566 // MBlazeJmpLink = #chain, #target_address, #opt_in_flags...
567 // = Chain, Callee, Reg#1, Reg#2, ...
568 //
569 // Returns a chain & a flag for retval copy to use.
570 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
571 SmallVector Ops;
572 Ops.push_back(Chain);
573 Ops.push_back(Callee);
574
575 // Add argument registers to the end of the list so that they are
576 // known live into the call.
577 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
578 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
579 RegsToPass[i].second.getValueType()));
580 }
581
582 if (InFlag.getNode())
583 Ops.push_back(InFlag);
584
585 Chain = DAG.getNode(MBlazeISD::JmpLink, dl, NodeTys, &Ops[0], Ops.size());
586 InFlag = Chain.getValue(1);
587
588 // Create the CALLSEQ_END node.
589 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true),
590 DAG.getIntPtrConstant(0, true), InFlag);
591 if (!Ins.empty())
592 InFlag = Chain.getValue(1);
593
594 // Handle result values, copying them out of physregs into vregs that we
595 // return.
596 return LowerCallResult(Chain, InFlag, CallConv, isVarArg,
597 Ins, dl, DAG, InVals);
598 }
599
600 /// LowerCallResult - Lower the result values of a call into the
601 /// appropriate copies out of appropriate physical registers.
602 SDValue MBlazeTargetLowering::
603 LowerCallResult(SDValue Chain, SDValue InFlag, CallingConv::ID CallConv,
604 bool isVarArg, const SmallVectorImpl &Ins,
605 DebugLoc dl, SelectionDAG &DAG,
606 SmallVectorImpl &InVals) {
607 // Assign locations to each value returned by this call.
608 SmallVector RVLocs;
609 CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
610 RVLocs, *DAG.getContext());
611
612 CCInfo.AnalyzeCallResult(Ins, RetCC_MBlaze);
613
614 // Copy all of the result registers out of their specified physreg.
615 for (unsigned i = 0; i != RVLocs.size(); ++i) {
616 Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(),
617 RVLocs[i].getValVT(), InFlag).getValue(1);
618 InFlag = Chain.getValue(2);
619 InVals.push_back(Chain.getValue(0));
620 }
621
622 return Chain;
623 }
624
625 //===----------------------------------------------------------------------===//
626 // Formal Arguments Calling Convention Implementation
627 //===----------------------------------------------------------------------===//
628
629 /// LowerFormalArguments - transform physical registers into
630 /// virtual registers and generate load operations for
631 /// arguments places on the stack.
632 /// TODO: isVarArg
633 SDValue MBlazeTargetLowering::
634 LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
635 const SmallVectorImpl &Ins,
636 DebugLoc dl, SelectionDAG &DAG,
637 SmallVectorImpl &InVals) {
638 MachineFunction &MF = DAG.getMachineFunction();
639 MachineFrameInfo *MFI = MF.getFrameInfo();
640 MBlazeFunctionInfo *MBlazeFI = MF.getInfo();
641
642 unsigned StackReg = MF.getTarget().getRegisterInfo()->getFrameRegister(MF);
643
644 // Assign locations to all of the incoming arguments.
645 SmallVector ArgLocs;
646 CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
647 ArgLocs, *DAG.getContext());
648
649 CCInfo.AnalyzeFormalArguments(Ins, CC_MBlaze);
650 SDValue StackPtr;
651
652 unsigned FirstStackArgLoc = 4;
653
654 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
655 CCValAssign &VA = ArgLocs[i];
656
657 // Arguments stored on registers
658 if (VA.isRegLoc()) {
659 EVT RegVT = VA.getLocVT();
660 TargetRegisterClass *RC = 0;
661
662 if (RegVT == MVT::i32)
663 RC = MBlaze::CPURegsRegisterClass;
664 else if (RegVT == MVT::f32)
665 RC = MBlaze::FGR32RegisterClass;
666 else
667 llvm_unreachable("RegVT not supported by LowerFormalArguments");
668
669 // Transform the arguments stored on
670 // physical registers into virtual ones
671 unsigned Reg = MF.addLiveIn(VA.getLocReg(), RC);
672 SDValue ArgValue = DAG.getCopyFromReg(Chain, dl, Reg, RegVT);
673
674 // If this is an 8 or 16-bit value, it has been passed promoted
675 // to 32 bits. Insert an assert[sz]ext to capture this, then
676 // truncate to the right size.
677 if (VA.getLocInfo() != CCValAssign::Full) {
678 unsigned Opcode = 0;
679 if (VA.getLocInfo() == CCValAssign::SExt)
680 Opcode = ISD::AssertSext;
681 else if (VA.getLocInfo() == CCValAssign::ZExt)
682 Opcode = ISD::AssertZext;
683 if (Opcode)
684 ArgValue = DAG.getNode(Opcode, dl, RegVT, ArgValue,
685 DAG.getValueType(VA.getValVT()));
686 ArgValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), ArgValue);
687 }
688
689 InVals.push_back(ArgValue);
690
691 // To meet ABI, when VARARGS are passed on registers, the registers
692 // must have their values written to the caller stack frame.
693 if (isVarArg) {
694 if (StackPtr.getNode() == 0)
695 StackPtr = DAG.getRegister(StackReg, getPointerTy());
696
697 // The stack pointer offset is relative to the caller stack frame.
698 // Since the real stack size is unknown here, a negative SPOffset
699 // is used so there's a way to adjust these offsets when the stack
700 // size get known (on EliminateFrameIndex). A dummy SPOffset is
701 // used instead of a direct negative address (which is recorded to
702 // be used on emitPrologue) to avoid mis-calc of the first stack
703 // offset on PEI::calculateFrameObjectOffsets.
704 // Arguments are always 32-bit.
705 int FI = MFI->CreateFixedObject(4, 0, true, false);
706 MBlazeFI->recordStoreVarArgsFI(FI, -(FirstStackArgLoc+(i*4)));
707 SDValue PtrOff = DAG.getFrameIndex(FI, getPointerTy());
708
709 // emit ISD::STORE whichs stores the
710 // parameter value to a stack Location
711 InVals.push_back(DAG.getStore(Chain, dl, ArgValue, PtrOff, NULL, 0,
712 false, false, 0));
713 }
714
715 } else { // VA.isRegLoc()
716
717 // sanity check
718 assert(VA.isMemLoc());
719
720 // The stack pointer offset is relative to the caller stack frame.
721 // Since the real stack size is unknown here, a negative SPOffset
722 // is used so there's a way to adjust these offsets when the stack
723 // size get known (on EliminateFrameIndex). A dummy SPOffset is
724 // used instead of a direct negative address (which is recorded to
725 // be used on emitPrologue) to avoid mis-calc of the first stack
726 // offset on PEI::calculateFrameObjectOffsets.
727 // Arguments are always 32-bit.
728 unsigned ArgSize = VA.getLocVT().getSizeInBits()/8;
729 int FI = MFI->CreateFixedObject(ArgSize, 0, true, false);
730 MBlazeFI->recordLoadArgsFI(FI, -(ArgSize+
731 (FirstStackArgLoc + VA.getLocMemOffset())));
732
733 // Create load nodes to retrieve arguments from the stack
734 SDValue FIN = DAG.getFrameIndex(FI, getPointerTy());
735 InVals.push_back(DAG.getLoad(VA.getValVT(), dl, Chain, FIN, NULL, 0,
736 false, false, 0));
737 }
738 }
739
740 return Chain;
741 }
742
743 //===----------------------------------------------------------------------===//
744 // Return Value Calling Convention Implementation
745 //===----------------------------------------------------------------------===//
746
747 SDValue MBlazeTargetLowering::
748 LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
749 const SmallVectorImpl &Outs,
750 DebugLoc dl, SelectionDAG &DAG) {
751 // CCValAssign - represent the assignment of
752 // the return value to a location
753 SmallVector RVLocs;
754
755 // CCState - Info about the registers and stack slot.
756 CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
757 RVLocs, *DAG.getContext());
758
759 // Analize return values.
760 CCInfo.AnalyzeReturn(Outs, RetCC_MBlaze);
761
762 // If this is the first return lowered for this function, add
763 // the regs to the liveout set for the function.
764 if (DAG.getMachineFunction().getRegInfo().liveout_empty()) {
765 for (unsigned i = 0; i != RVLocs.size(); ++i)
766 if (RVLocs[i].isRegLoc())
767 DAG.getMachineFunction().getRegInfo().addLiveOut(RVLocs[i].getLocReg());
768 }
769
770 SDValue Flag;
771
772 // Copy the result values into the output registers.
773 for (unsigned i = 0; i != RVLocs.size(); ++i) {
774 CCValAssign &VA = RVLocs[i];
775 assert(VA.isRegLoc() && "Can only return in registers!");
776
777 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
778 Outs[i].Val, Flag);
779
780 // guarantee that all emitted copies are
781 // stuck together, avoiding something bad
782 Flag = Chain.getValue(1);
783 }
784
785 // Return on MBlaze is always a "rtsd R15, 8"
786 if (Flag.getNode())
787 return DAG.getNode(MBlazeISD::Ret, dl, MVT::Other,
788 Chain, DAG.getRegister(MBlaze::R15, MVT::i32), Flag);
789 else // Return Void
790 return DAG.getNode(MBlazeISD::Ret, dl, MVT::Other,
791 Chain, DAG.getRegister(MBlaze::R15, MVT::i32));
792 }
793
794 //===----------------------------------------------------------------------===//
795 // MBlaze Inline Assembly Support
796 //===----------------------------------------------------------------------===//
797
798 /// getConstraintType - Given a constraint letter, return the type of
799 /// constraint it is for this target.
800 MBlazeTargetLowering::ConstraintType MBlazeTargetLowering::
801 getConstraintType(const std::string &Constraint) const
802 {
803 // MBlaze specific constrainy
804 //
805 // 'd' : An address register. Equivalent to r.
806 // 'y' : Equivalent to r; retained for
807 // backwards compatibility.
808 // 'f' : Floating Point registers.
809 if (Constraint.size() == 1) {
810 switch (Constraint[0]) {
811 default : break;
812 case 'd':
813 case 'y':
814 case 'f':
815 return C_RegisterClass;
816 break;
817 }
818 }
819 return TargetLowering::getConstraintType(Constraint);
820 }
821
822 /// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),
823 /// return a list of registers that can be used to satisfy the constraint.
824 /// This should only be used for C_RegisterClass constraints.
825 std::pair MBlazeTargetLowering::
826 getRegForInlineAsmConstraint(const std::string &Constraint, EVT VT) const {
827 if (Constraint.size() == 1) {
828 switch (Constraint[0]) {
829 case 'r':
830 return std::make_pair(0U, MBlaze::CPURegsRegisterClass);
831 case 'f':
832 if (VT == MVT::f32)
833 return std::make_pair(0U, MBlaze::FGR32RegisterClass);
834 }
835 }
836 return TargetLowering::getRegForInlineAsmConstraint(Constraint, VT);
837 }
838
839 /// Given a register class constraint, like 'r', if this corresponds directly
840 /// to an LLVM register class, return a register of 0 and the register class
841 /// pointer.
842 std::vector MBlazeTargetLowering::
843 getRegClassForInlineAsmConstraint(const std::string &Constraint, EVT VT) const {
844 if (Constraint.size() != 1)
845 return std::vector();
846
847 switch (Constraint[0]) {
848 default : break;
849 case 'r':
850 // GCC MBlaze Constraint Letters
851 case 'd':
852 case 'y':
853 return make_vector(
854 MBlaze::R3, MBlaze::R4, MBlaze::R5, MBlaze::R6,
855 MBlaze::R7, MBlaze::R9, MBlaze::R10, MBlaze::R11,
856 MBlaze::R12, MBlaze::R19, MBlaze::R20, MBlaze::R21,
857 MBlaze::R22, MBlaze::R23, MBlaze::R24, MBlaze::R25,
858 MBlaze::R26, MBlaze::R27, MBlaze::R28, MBlaze::R29,
859 MBlaze::R30, MBlaze::R31, 0);
860
861 case 'f':
862 return make_vector(
863 MBlaze::F3, MBlaze::F4, MBlaze::F5, MBlaze::F6,
864 MBlaze::F7, MBlaze::F9, MBlaze::F10, MBlaze::F11,
865 MBlaze::F12, MBlaze::F19, MBlaze::F20, MBlaze::F21,
866 MBlaze::F22, MBlaze::F23, MBlaze::F24, MBlaze::F25,
867 MBlaze::F26, MBlaze::F27, MBlaze::F28, MBlaze::F29,
868 MBlaze::F30, MBlaze::F31, 0);
869 }
870 return std::vector();
871 }
872
873 bool MBlazeTargetLowering::
874 isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
875 // The MBlaze target isn't yet aware of offsets.
876 return false;
877 }
878
879 bool MBlazeTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT) const {
880 return VT != MVT::f32;
881 }
0 //===-- MBlazeISelLowering.h - MBlaze DAG Lowering Interface ----*- 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 defines the interfaces that MBlaze uses to lower LLVM code into a
10 // selection DAG.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef MBlazeISELLOWERING_H
15 #define MBlazeISELLOWERING_H
16
17 #include "llvm/CodeGen/SelectionDAG.h"
18 #include "llvm/Target/TargetLowering.h"
19 #include "MBlaze.h"
20 #include "MBlazeSubtarget.h"
21
22 namespace llvm {
23 namespace MBlazeCC {
24 enum CC {
25 FIRST = 0,
26 EQ,
27 NE,
28 GT,
29 LT,
30 GE,
31 LE
32 };
33 }
34
35 namespace MBlazeISD {
36 enum NodeType {
37 // Start the numbering from where ISD NodeType finishes.
38 FIRST_NUMBER = ISD::BUILTIN_OP_END,
39
40 // Jump and link (call)
41 JmpLink,
42
43 // Handle gp_rel (small data/bss sections) relocation.
44 GPRel,
45
46 // Select CC Pseudo Instruction
47 Select_CC,
48
49 // Wrap up multiple types of instructions
50 Wrap,
51
52 // Integer Compare
53 ICmp,
54
55 // Return
56 Ret
57 };
58 }
59
60 //===--------------------------------------------------------------------===//
61 // TargetLowering Implementation
62 //===--------------------------------------------------------------------===//
63
64 class MBlazeTargetLowering : public TargetLowering {
65 public:
66
67 explicit MBlazeTargetLowering(MBlazeTargetMachine &TM);
68
69 /// LowerOperation - Provide custom lowering hooks for some operations.
70 virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
71
72 /// getTargetNodeName - This method returns the name of a target specific
73 // DAG node.
74 virtual const char *getTargetNodeName(unsigned Opcode) const;
75
76 /// getSetCCResultType - get the ISD::SETCC result ValueType
77 MVT::SimpleValueType getSetCCResultType(EVT VT) const;
78
79 virtual unsigned getFunctionAlignment(const Function *F) const;
80 private:
81 // Subtarget Info
82 const MBlazeSubtarget *Subtarget;
83
84
85 // Lower Operand helpers
86 SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
87 CallingConv::ID CallConv, bool isVarArg,
88 const SmallVectorImpl &Ins,
89 DebugLoc dl, SelectionDAG &DAG,
90 SmallVectorImpl &InVals);
91
92 // Lower Operand specifics
93 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG);
94 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG);
95 SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG);
96 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG);
97 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG);
98
99 virtual SDValue
100 LowerFormalArguments(SDValue Chain,
101 CallingConv::ID CallConv, bool isVarArg,
102 const SmallVectorImpl &Ins,
103 DebugLoc dl, SelectionDAG &DAG,
104 SmallVectorImpl &InVals);
105
106 virtual SDValue
107 LowerCall(SDValue Chain, SDValue Callee,
108 CallingConv::ID CallConv, bool isVarArg,
109 bool &isTailCall,
110 const SmallVectorImpl &Outs,
111 const SmallVectorImpl &Ins,
112 DebugLoc dl, SelectionDAG &DAG,
113 SmallVectorImpl &InVals);
114
115 virtual SDValue
116 LowerReturn(SDValue Chain,
117 CallingConv::ID CallConv, bool isVarArg,
118 const SmallVectorImpl &Outs,
119 DebugLoc dl, SelectionDAG &DAG);
120
121 virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI,
122 MachineBasicBlock *MBB,
123 DenseMap *EM) const;
124
125 // Inline asm support
126 ConstraintType getConstraintType(const std::string &Constraint) const;
127
128 std::pair
129 getRegForInlineAsmConstraint(const std::string &Constraint,
130 EVT VT) const;
131
132 std::vector
133 getRegClassForInlineAsmConstraint(const std::string &Constraint,
134 EVT VT) const;
135
136 virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
137
138 /// isFPImmLegal - Returns true if the target can instruction select the
139 /// specified FP immediate natively. If false, the legalizer will
140 /// materialize the FP immediate as a load from a constant pool.
141 virtual bool isFPImmLegal(const APFloat &Imm, EVT VT) const;
142 };
143 }
144
145 #endif // MBlazeISELLOWERING_H
0 //===- MBlazeInstrFPU.td - MBlaze FPU Instruction defs ----------*- 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 // MBlaze profiles and nodes
11 //===----------------------------------------------------------------------===//
12
13 //===----------------------------------------------------------------------===//
14 // MBlaze Operand, Complex Patterns and Transformations Definitions.
15 //===----------------------------------------------------------------------===//
16
17 //===----------------------------------------------------------------------===//
18 // Memory Access Instructions
19 //===----------------------------------------------------------------------===//
20 class LoadFM op, string instr_asm, PatFrag OpNode> :
21 TA
22 !strconcat(instr_asm, " $dst, $addr"),
23 [(set FGR32:$dst, (OpNode xaddr:$addr))], IILoad>;
24
25 class LoadFMI op, string instr_asm, PatFrag OpNode> :
26 TAI
27 !strconcat(instr_asm, " $dst, $addr"),
28 [(set FGR32:$dst, (OpNode iaddr:$addr))], IILoad>;
29
30 class StoreFM op, string instr_asm, PatFrag OpNode> :
31 TA
32 !strconcat(instr_asm, " $dst, $addr"),
33 [(OpNode FGR32:$dst, xaddr:$addr)], IIStore>;
34
35 class StoreFMI op, string instr_asm, PatFrag OpNode> :
36 TAI
37 !strconcat(instr_asm, " $dst, $addr"),
38 [(OpNode FGR32:$dst, iaddr:$addr)], IIStore>;
39
40 class ArithF op, bits<11> flags, string instr_asm, SDNode OpNode,
41 InstrItinClass itin> :
42 TA
43 !strconcat(instr_asm, " $dst, $b, $c"),
44 [(set FGR32:$dst, (OpNode FGR32:$b, FGR32:$c))], itin>;
45
46 class CmpFN op, bits<11> flags, string instr_asm,
47 InstrItinClass itin> :
48 TA
49 !strconcat(instr_asm, " $dst, $b, $c"),
50 [], itin>;
51
52 class ArithFR op, bits<11> flags, string instr_asm, SDNode OpNode,
53 InstrItinClass itin> :
54 TA
55 !strconcat(instr_asm, " $dst, $c, $b"),
56 [(set FGR32:$dst, (OpNode FGR32:$b, FGR32:$c))], itin>;
57
58 class ArithF2 op, bits<11> flags, string instr_asm,
59 InstrItinClass itin> :
60 TF
61 !strconcat(instr_asm, " $dst, $b"),
62 [], itin>;
63
64 class ArithIF op, bits<11> flags, string instr_asm,
65 InstrItinClass itin> :
66 TF
67 !strconcat(instr_asm, " $dst, $b"),
68 [], itin>;
69
70 class ArithFI op, bits<11> flags, string instr_asm,
71 InstrItinClass itin> :
72 TF
73 !strconcat(instr_asm, " $dst, $b"),
74 [], itin>;
75
76 class LogicF op, string instr_asm> :
77 TAI
78 !strconcat(instr_asm, " $dst, $b, $c"),
79 [],
80 IIAlu>;
81
82 class LogicFI op, string instr_asm> :
83 TAI
84 !strconcat(instr_asm, " $dst, $b, $c"),
85 [],
86 IIAlu>;
87
88 //===----------------------------------------------------------------------===//
89 // Pseudo instructions
90 //===----------------------------------------------------------------------===//
91
92 //===----------------------------------------------------------------------===//
93 // FPU Arithmetic Instructions
94 //===----------------------------------------------------------------------===//
95 let Predicates=[HasFPU] in {
96 def FOR : LogicF<0x28, "or ">;
97 def FORI : LogicFI<0x28, "ori ">;
98 def FADD : ArithF<0x16, 0x000, "fadd ", fadd, IIAlu>;
99 def FRSUB : ArithFR<0x16, 0x080, "frsub ", fsub, IIAlu>;
100 def FMUL : ArithF<0x16, 0x100, "fmul ", fmul, IIAlu>;
101 def FDIV : ArithF<0x16, 0x180, "fdiv ", fdiv, IIAlu>;
102
103 def LWF : LoadFM<0x32, "lw ", load>;
104 def LWFI : LoadFMI<0x32, "lwi ", load>;
105
106 def SWF : StoreFM<0x32, "sw ", store>;
107 def SWFI : StoreFMI<0x32, "swi ", store>;
108 }
109
110 let Predicates=[HasFPU,HasSqrt] in {
111 def FLT : ArithIF<0x16, 0x280, "flt ", IIAlu>;
112 def FINT : ArithFI<0x16, 0x300, "fint ", IIAlu>;
113 def FSQRT : ArithF2<0x16, 0x300, "fsqrt ", IIAlu>;
114 }
115
116 let isAsCheapAsAMove = 1 in {
117 def FCMP_UN : CmpFN<0x16, 0x200, "fcmp.un", IIAlu>;
118 def FCMP_LT : CmpFN<0x16, 0x210, "fcmp.lt", IIAlu>;
119 def FCMP_EQ : CmpFN<0x16, 0x220, "fcmp.eq", IIAlu>;
120 def FCMP_LE : CmpFN<0x16, 0x230, "fcmp.le", IIAlu>;
121 def FCMP_GT : CmpFN<0x16, 0x240, "fcmp.gt", IIAlu>;
122 def FCMP_NE : CmpFN<0x16, 0x250, "fcmp.ne", IIAlu>;
123 def FCMP_GE : CmpFN<0x16, 0x260, "fcmp.ge", IIAlu>;
124 }
125
126
127 let usesCustomInserter = 1 in {
128 def Select_FCC : MBlazePseudo<(outs FGR32:$dst),
129 (ins FGR32:$T, FGR32:$F, CPURegs:$CMP, i32imm:$CC),
130 "; SELECT_FCC PSEUDO!",
131 []>;
132 }
133
134 // Floating point conversions
135 let Predicates=[HasFPU] in {
136 def : Pat<(sint_to_fp CPURegs:$V), (FLT CPURegs:$V)>;
137 def : Pat<(fp_to_sint FGR32:$V), (FINT FGR32:$V)>;
138 def : Pat<(fsqrt FGR32:$V), (FSQRT FGR32:$V)>;
139 }
140
141 // SET_CC operations
142 let Predicates=[HasFPU] in {
143 def : Pat<(setcc FGR32:$L, FGR32:$R, SETEQ),
144 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
145 (FCMP_EQ FGR32:$L, FGR32:$R), 2)>;
146 def : Pat<(setcc FGR32:$L, FGR32:$R, SETNE),
147 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
148 (FCMP_EQ FGR32:$L, FGR32:$R), 1)>;
149 def : Pat<(setcc FGR32:$L, FGR32:$R, SETOEQ),
150 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
151 (FCMP_EQ FGR32:$L, FGR32:$R), 2)>;
152 def : Pat<(setcc FGR32:$L, FGR32:$R, SETONE),
153 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
154 (XOR (FCMP_UN FGR32:$L, FGR32:$R),
155 (FCMP_EQ FGR32:$L, FGR32:$R)), 2)>;
156 def : Pat<(setcc FGR32:$L, FGR32:$R, SETONE),
157 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
158 (OR (FCMP_UN FGR32:$L, FGR32:$R),
159 (FCMP_EQ FGR32:$L, FGR32:$R)), 2)>;
160 def : Pat<(setcc FGR32:$L, FGR32:$R, SETGT),
161 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
162 (FCMP_GT FGR32:$L, FGR32:$R), 2)>;
163 def : Pat<(setcc FGR32:$L, FGR32:$R, SETLT),
164 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
165 (FCMP_LT FGR32:$L, FGR32:$R), 2)>;
166 def : Pat<(setcc FGR32:$L, FGR32:$R, SETGE),
167 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
168 (FCMP_GE FGR32:$L, FGR32:$R), 2)>;
169 def : Pat<(setcc FGR32:$L, FGR32:$R, SETLE),
170 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
171 (FCMP_LE FGR32:$L, FGR32:$R), 2)>;
172 def : Pat<(setcc FGR32:$L, FGR32:$R, SETOGT),
173 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
174 (FCMP_GT FGR32:$L, FGR32:$R), 2)>;
175 def : Pat<(setcc FGR32:$L, FGR32:$R, SETOLT),
176 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
177 (FCMP_LT FGR32:$L, FGR32:$R), 2)>;
178 def : Pat<(setcc FGR32:$L, FGR32:$R, SETOGE),
179 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
180 (FCMP_GE FGR32:$L, FGR32:$R), 2)>;
181 def : Pat<(setcc FGR32:$L, FGR32:$R, SETOLE),
182 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
183 (FCMP_LE FGR32:$L, FGR32:$R), 2)>;
184 def : Pat<(setcc FGR32:$L, FGR32:$R, SETUEQ),
185 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
186 (OR (FCMP_UN FGR32:$L, FGR32:$R),
187 (FCMP_EQ FGR32:$L, FGR32:$R)), 2)>;
188 def : Pat<(setcc FGR32:$L, FGR32:$R, SETUNE),
189 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
190 (FCMP_NE FGR32:$L, FGR32:$R), 2)>;
191 def : Pat<(setcc FGR32:$L, FGR32:$R, SETUGT),
192 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
193 (OR (FCMP_UN FGR32:$L, FGR32:$R),
194 (FCMP_GT FGR32:$L, FGR32:$R)), 2)>;
195 def : Pat<(setcc FGR32:$L, FGR32:$R, SETULT),
196 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
197 (OR (FCMP_UN FGR32:$L, FGR32:$R),
198 (FCMP_LT FGR32:$L, FGR32:$R)), 2)>;
199 def : Pat<(setcc FGR32:$L, FGR32:$R, SETUGE),
200 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
201 (OR (FCMP_UN FGR32:$L, FGR32:$R),
202 (FCMP_GE FGR32:$L, FGR32:$R)), 2)>;
203 def : Pat<(setcc FGR32:$L, FGR32:$R, SETULE),
204 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
205 (OR (FCMP_UN FGR32:$L, FGR32:$R),
206 (FCMP_LE FGR32:$L, FGR32:$R)), 2)>;
207 def : Pat<(setcc FGR32:$L, FGR32:$R, SETO),
208 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
209 (FCMP_UN FGR32:$L, FGR32:$R), 1)>;
210 def : Pat<(setcc FGR32:$L, FGR32:$R, SETUO),
211 (Select_CC (ADDI R0, 1), (ADDI R0, 0),
212 (FCMP_UN FGR32:$L, FGR32:$R), 2)>;
213 }
214
215 // SELECT operations
216 def : Pat<(select CPURegs:$C, FGR32:$T, FGR32:$F),
217 (Select_FCC FGR32:$T, FGR32:$F, CPURegs:$C, 2)>;
218
219 //===----------------------------------------------------------------------===//
220 // Patterns for Floating Point Instructions
221 //===----------------------------------------------------------------------===//
222 def : Pat<(f32 fpimm:$imm), (FORI F0, fpimm:$imm)>;
0 //===- MBlazeInstrFSL.td - MBlaze FSL Instruction defs ----------*- 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 // FSL Instruction Formats
11 //===----------------------------------------------------------------------===//
12 class FSLGetD op, bits<11> flags, string instr_asm, Intrinsic OpNode> :
13 TA
14 !strconcat(instr_asm, " $dst, $b"),
15 [(set CPURegs:$dst, (OpNode CPURegs:$b))], IIAlu>;
16
17 class FSLGet op, string instr_asm, Intrinsic OpNode> :
18 TAI
19 !strconcat(instr_asm, " $dst, $b"),
20 [(set CPURegs:$dst, (OpNode immZExt4:$b))], IIAlu>;
21
22 class FSLPutD op, bits<11> flags, string instr_asm, Intrinsic OpNode> :
23 TA
24 !strconcat(instr_asm, " $v, $b"),
25 [(OpNode CPURegs:$v, CPURegs:$b)], IIAlu>;
26
27 class FSLPut op, string instr_asm, Intrinsic OpNode> :
28 TAI
29 !strconcat(instr_asm, " $v, $b"),
30 [(OpNode CPURegs:$v, immZExt4:$b)], IIAlu>;
31
32 class FSLPutTD op, bits<11> flags, string instr_asm, Intrinsic OpNode> :
33 TA
34 !strconcat(instr_asm, " $b"),
35 [(OpNode CPURegs:$b)], IIAlu>;
36
37 class FSLPutT op, string instr_asm, Intrinsic OpNode> :
38 TAI
39 !strconcat(instr_asm, " $b"),
40 [(OpNode immZExt4:$b)], IIAlu>;
41
42 //===----------------------------------------------------------------------===//
43 // FSL Get Instructions
44 //===----------------------------------------------------------------------===//
45 def GET : FSLGet<0x1B, "get ", int_mblaze_fsl_get>;
46 def AGET : FSLGet<0x1B, "aget ", int_mblaze_fsl_aget>;
47 def CGET : FSLGet<0x1B, "cget ", int_mblaze_fsl_cget>;
48 def CAGET : FSLGet<0x1B, "caget ", int_mblaze_fsl_caget>;
49 def EGET : FSLGet<0x1B, "eget ", int_mblaze_fsl_eget>;
50 def EAGET : FSLGet<0x1B, "eaget ", int_mblaze_fsl_eaget>;
51 def ECGET : FSLGet<0x1B, "ecget ", int_mblaze_fsl_ecget>;
52 def ECAGET : FSLGet<0x1B, "ecaget ", int_mblaze_fsl_ecaget>;
53 def NGET : FSLGet<0x1B, "nget ", int_mblaze_fsl_nget>;
54 def NAGET : FSLGet<0x1B, "naget ", int_mblaze_fsl_naget>;
55 def NCGET : FSLGet<0x1B, "ncget ", int_mblaze_fsl_ncget>;
56 def NCAGET : FSLGet<0x1B, "ncaget ", int_mblaze_fsl_ncaget>;
57 def NEGET : FSLGet<0x1B, "neget ", int_mblaze_fsl_neget>;
58 def NEAGET : FSLGet<0x1B, "neaget ", int_mblaze_fsl_neaget>;
59 def NECGET : FSLGet<0x1B, "necget ", int_mblaze_fsl_necget>;
60 def NECAGET : FSLGet<0x1B, "necaget ", int_mblaze_fsl_necaget>;
61 def TGET : FSLGet<0x1B, "tget ", int_mblaze_fsl_tget>;
62 def TAGET : FSLGet<0x1B, "taget ", int_mblaze_fsl_taget>;
63 def TCGET : FSLGet<0x1B, "tcget ", int_mblaze_fsl_tcget>;
64 def TCAGET : FSLGet<0x1B, "tcaget ", int_mblaze_fsl_tcaget>;
65 def TEGET : FSLGet<0x1B, "teget ", int_mblaze_fsl_teget>;
66 def TEAGET : FSLGet<0x1B, "teaget ", int_mblaze_fsl_teaget>;
67 def TECGET : FSLGet<0x1B, "tecget ", int_mblaze_fsl_tecget>;
68 def TECAGET : FSLGet<0x1B, "tecaget ", int_mblaze_fsl_tecaget>;
69 def TNGET : FSLGet<0x1B, "tnget ", int_mblaze_fsl_tnget>;
70 def TNAGET : FSLGet<0x1B, "tnaget ", int_mblaze_fsl_tnaget>;
71 def TNCGET : FSLGet<0x1B, "tncget ", int_mblaze_fsl_tncget>;
72 def TNCAGET : FSLGet<0x1B, "tncaget ", int_mblaze_fsl_tncaget>;
73 def TNEGET : FSLGet<0x1B, "tneget ", int_mblaze_fsl_tneget>;
74 def TNEAGET : FSLGet<0x1B, "tneaget ", int_mblaze_fsl_tneaget>;
75 def TNECGET : FSLGet<0x1B, "tnecget ", int_mblaze_fsl_tnecget>;
76 def TNECAGET : FSLGet<0x1B, "tnecaget ", int_mblaze_fsl_tnecaget>;
77
78 //===----------------------------------------------------------------------===//
79 // FSL Dynamic Get Instructions
80 //===----------------------------------------------------------------------===//
81 def GETD : FSLGetD<0x1B, 0x00, "getd ", int_mblaze_fsl_get>;
82 def AGETD : FSLGetD<0x1B, 0x00, "agetd ", int_mblaze_fsl_aget>;
83 def CGETD : FSLGetD<0x1B, 0x00, "cgetd ", int_mblaze_fsl_cget>;
84 def CAGETD : FSLGetD<0x1B, 0x00, "cagetd ", int_mblaze_fsl_caget>;
85 def EGETD : FSLGetD<0x1B, 0x00, "egetd ", int_mblaze_fsl_eget>;
86 def EAGETD : FSLGetD<0x1B, 0x00, "eagetd ", int_mblaze_fsl_eaget>;
87 def ECGETD : FSLGetD<0x1B, 0x00, "ecgetd ", int_mblaze_fsl_ecget>;
88 def ECAGETD : FSLGetD<0x1B, 0x00, "ecagetd ", int_mblaze_fsl_ecaget>;
89 def NGETD : FSLGetD<0x1B, 0x00, "ngetd ", int_mblaze_fsl_nget>;
90 def NAGETD : FSLGetD<0x1B, 0x00, "nagetd ", int_mblaze_fsl_naget>;
91 def NCGETD : FSLGetD<0x1B, 0x00, "ncgetd ", int_mblaze_fsl_ncget>;
92 def NCAGETD : FSLGetD<0x1B, 0x00, "ncagetd ", int_mblaze_fsl_ncaget>;
93 def NEGETD : FSLGetD<0x1B, 0x00, "negetd ", int_mblaze_fsl_neget>;
94 def NEAGETD : FSLGetD<0x1B, 0x00, "neagetd ", int_mblaze_fsl_neaget>;
95 def NECGETD : FSLGetD<0x1B, 0x00, "necgetd ", int_mblaze_fsl_necget>;
96 def NECAGETD : FSLGetD<0x1B, 0x00, "necagetd ", int_mblaze_fsl_necaget>;
97 def TGETD : FSLGetD<0x1B, 0x00, "tgetd ", int_mblaze_fsl_tget>;
98 def TAGETD : FSLGetD<0x1B, 0x00, "tagetd ", int_mblaze_fsl_taget>;
99 def TCGETD : FSLGetD<0x1B, 0x00, "tcgetd ", int_mblaze_fsl_tcget>;
100 def TCAGETD : FSLGetD<0x1B, 0x00, "tcagetd ", int_mblaze_fsl_tcaget>;
101 def TEGETD : FSLGetD<0x1B, 0x00, "tegetd ", int_mblaze_fsl_teget>;
102 def TEAGETD : FSLGetD<0x1B, 0x00, "teagetd ", int_mblaze_fsl_teaget>;
103 def TECGETD : FSLGetD<0x1B, 0x00, "tecgetd ", int_mblaze_fsl_tecget>;
104 def TECAGETD : FSLGetD<0x1B, 0x00, "tecagetd ", int_mblaze_fsl_tecaget>;
105 def TNGETD : FSLGetD<0x1B, 0x00, "tngetd ", int_mblaze_fsl_tnget>;
106 def TNAGETD : FSLGetD<0x1B, 0x00, "tnagetd ", int_mblaze_fsl_tnaget>;
107 def TNCGETD : FSLGetD<0x1B, 0x00, "tncgetd ", int_mblaze_fsl_tncget>;
108 def TNCAGETD : FSLGetD<0x1B, 0x00, "tncagetd ", int_mblaze_fsl_tncaget>;
109 def TNEGETD : FSLGetD<0x1B, 0x00, "tnegetd ", int_mblaze_fsl_tneget>;
110 def TNEAGETD : FSLGetD<0x1B, 0x00, "tneagetd ", int_mblaze_fsl_tneaget>;
111 def TNECGETD : FSLGetD<0x1B, 0x00, "tnecgetd ", int_mblaze_fsl_tnecget>;
112 def TNECAGETD : FSLGetD<0x1B, 0x00, "tnecagetd", int_mblaze_fsl_tnecaget>;
113
114 //===----------------------------------------------------------------------===//
115 // FSL Put Instructions
116 //===----------------------------------------------------------------------===//
117 def PUT : FSLPut<0x1B, "put ", int_mblaze_fsl_put>;
118 def APUT : FSLPut<0x1B, "aput ", int_mblaze_fsl_aput>;
119 def CPUT : FSLPut<0x1B, "cput ", int_mblaze_fsl_cput>;
120 def CAPUT : FSLPut<0x1B, "caput ", int_mblaze_fsl_caput>;
121 def NPUT : FSLPut<0x1B, "nput ", int_mblaze_fsl_nput>;
122 def NAPUT : FSLPut<0x1B, "naput ", int_mblaze_fsl_naput>;
123 def NCPUT : FSLPut<0x1B, "ncput ", int_mblaze_fsl_ncput>;
124 def NCAPUT : FSLPut<0x1B, "ncaput ", int_mblaze_fsl_ncaput>;
125 def TPUT : FSLPutT<0x1B, "tput ", int_mblaze_fsl_tput>;
126 def TAPUT : FSLPutT<0x1B, "taput ", int_mblaze_fsl_taput>;
127 def TCPUT : FSLPutT<0x1B, "tcput ", int_mblaze_fsl_tcput>;
128 def TCAPUT : FSLPutT<0x1B, "tcaput ", int_mblaze_fsl_tcaput>;
129 def TNPUT : FSLPutT<0x1B, "tnput ", int_mblaze_fsl_tnput>;
130 def TNAPUT : FSLPutT<0x1B, "tnaput ", int_mblaze_fsl_tnaput>;
131 def TNCPUT : FSLPutT<0x1B, "tncput ", int_mblaze_fsl_tncput>;
132 def TNCAPUT : FSLPutT<0x1B, "tncaput ", int_mblaze_fsl_tncaput>;
133
134 //===----------------------------------------------------------------------===//
135 // FSL Dynamic Put Instructions
136 //===----------------------------------------------------------------------===//
137 def PUTD : FSLPutD<0x1B, 0x00, "putd ", int_mblaze_fsl_put>;
138 def APUTD : FSLPutD<0x1B, 0x00, "aputd ", int_mblaze_fsl_aput>;
139 def CPUTD : FSLPutD<0x1B, 0x00, "cputd ", int_mblaze_fsl_cput>;
140 def CAPUTD : FSLPutD<0x1B, 0x00, "caputd ", int_mblaze_fsl_caput>;
141 def NPUTD : FSLPutD<0x1B, 0x00, "nputd ", int_mblaze_fsl_nput>;
142 def NAPUTD : FSLPutD<0x1B, 0x00, "naputd ", int_mblaze_fsl_naput>;
143 def NCPUTD : FSLPutD<0x1B, 0x00, "ncputd ", int_mblaze_fsl_ncput>;
144 def NCAPUTD : FSLPutD<0x1B, 0x00, "ncaputd ", int_mblaze_fsl_ncaput>;
145 def TPUTD : FSLPutTD<0x1B, 0x00, "tputd ", int_mblaze_fsl_tput>;
146 def TAPUTD : FSLPutTD<0x1B, 0x00, "taputd ", int_mblaze_fsl_taput>;
147 def TCPUTD : FSLPutTD<0x1B, 0x00, "tcputd ", int_mblaze_fsl_tcput>;
148 def TCAPUTD : FSLPutTD<0x1B, 0x00, "tcaputd ", int_mblaze_fsl_tcaput>;
149 def TNPUTD : FSLPutTD<0x1B, 0x00, "tnputd ", int_mblaze_fsl_tnput>;
150 def TNAPUTD : FSLPutTD<0x1B, 0x00, "tnaputd ", int_mblaze_fsl_tnaput>;
151 def TNCPUTD : FSLPutTD<0x1B, 0x00, "tncputd ", int_mblaze_fsl_tncput>;
152 def TNCAPUTD : FSLPutTD<0x1B, 0x00, "tncaputd ", int_mblaze_fsl_tncaput>;
0 //===- MBlazeInstrFormats.td - MB Instruction defs --------------*- 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 // Describe MBlaze instructions format
11 //
12 // CPU INSTRUCTION FORMATS
13 //
14 // opcode - operation code.
15 // rd - dst reg.
16 // ra - first src. reg.
17 // rb - second src. reg.
18 // imm16 - 16-bit immediate value.
19 //
20 //===----------------------------------------------------------------------===//
21
22 // Generic MBlaze Format
23 class MBlazeInst pattern,
24 InstrItinClass itin> : Instruction
25 {
26 field bits<32> Inst;
27
28 let Namespace = "MBlaze";
29
30 bits<6> opcode;
31
32 // Top 6 bits are the 'opcode' field
33 let Inst{0-5} = opcode;
34
35 dag OutOperandList = outs;
36 dag InOperandList = ins;
37
38 let AsmString = asmstr;
39 let Pattern = pattern;
40 let Itinerary = itin;
41 }
42
43 //===----------------------------------------------------------------------===//
44 // Pseudo instruction class
45 //===----------------------------------------------------------------------===//
46 class MBlazePseudo pattern>:
47 MBlazeInst;
48
49 //===----------------------------------------------------------------------===//
50 // Type A instruction class in MBlaze : <|opcode|rd|ra|rb|flags|>
51 //===----------------------------------------------------------------------===//
52
53 class TA op, bits<11> flags, dag outs, dag ins, string asmstr,
54 list pattern, InstrItinClass itin> :
55 MBlazeInst
56 {
57 bits<5> rd;
58 bits<5> ra;
59 bits<5> rb;
60
61 let opcode = op;
62
63 let Inst{6-10} = rd;
64 let Inst{11-15} = ra;
65 let Inst{16-20} = rb;
66 let Inst{21-31} = flags;
67 }
68
69 class TAI op, dag outs, dag ins, string asmstr,
70 list pattern, InstrItinClass itin> :
71 MBlazeInst
72 {
73 bits<5> rd;
74 bits<5> ra;
75 bits<16> imm16;
76
77 let opcode = op;
78
79 let Inst{6-10} = rd;
80 let Inst{11-15} = ra;
81 let Inst{16-31} = imm16;
82 }
83
84 class TIMM op, dag outs, dag ins, string asmstr,
85 list pattern, InstrItinClass itin> :
86 MBlazeInst
87 {
88 bits<5> ra;
89 bits<16> imm16;
90
91 let opcode = op;
92
93 let Inst{6-15} = 0;
94 let Inst{16-31} = imm16;
95 }
96
97 class TADDR op, dag outs, dag ins, string asmstr,
98 list pattern, InstrItinClass itin> :
99 MBlazeInst
100 {
101 bits<26> addr;
102
103 let opcode = op;
104
105 let Inst{6-31} = addr;
106 }
107
108 //===----------------------------------------------------------------------===//
109 // Type B instruction class in MBlaze : <|opcode|rd|ra|immediate|>
110 //===----------------------------------------------------------------------===//
111
112 class TB op, dag outs, dag ins, string asmstr, list pattern,
113 InstrItinClass itin> :
114 MBlazeInst
115 {
116 bits<5> rd;
117 bits<5> ra;
118 bits<16> imm16;
119
120 let opcode = op;
121
122 let Inst{6-10} = rd;
123 let Inst{11-15} = ra;
124 let Inst{16-31} = imm16;
125 }
126
127 //===----------------------------------------------------------------------===//
128 // Float instruction class in MBlaze : <|opcode|rd|ra|flags|>
129 //===----------------------------------------------------------------------===//
130
131 class TF op, bits<11> flags, dag outs, dag ins, string asmstr,
132 list pattern, InstrItinClass itin> :
133 MBlazeInst
134 {
135 bits<5> rd;
136 bits<5> ra;
137
138 let opcode = op;
139
140 let Inst{6-10} = rd;
141 let Inst{11-15} = ra;
142 let Inst{16-20} = 0;
143 let Inst{21-31} = flags;
144 }
145
146 //===----------------------------------------------------------------------===//
147 // Branch instruction class in MBlaze : <|opcode|rd|br|ra|flags|>
148 //===----------------------------------------------------------------------===//
149
150 class TBR op, bits<5> br, bits<11> flags, dag outs, dag ins,
151 string asmstr, list pattern, InstrItinClass itin> :
152 MBlazeInst
153 {
154 bits<5> ra;
155
156 let opcode = op;
157
158 let Inst{6-10} = 0;
159 let Inst{11-15} = br;
160 let Inst{16-20} = ra;
161 let Inst{21-31} = flags;
162 }
163
164 class TBRC op, bits<5> br, bits<11> flags, dag outs, dag ins,
165 string asmstr, list pattern, InstrItinClass itin> :
166 MBlazeInst
167 {
168 bits<5> ra;
169 bits<5> rb;
170
171 let opcode = op;
172
173 let Inst{6-10} = br;
174 let Inst{11-15} = ra;
175 let Inst{16-20} = rb;
176 let Inst{21-31} = flags;
177 }
178
179 class TBRL op, bits<5> br, bits<11> flags, dag outs, dag ins,
180 string asmstr, list pattern, InstrItinClass itin> :
181 MBlazeInst
182 {
183 bits<5> ra;
184
185 let opcode = op;
186
187 let Inst{6-10} = 0xF;
188 let Inst{11-15} = br;
189 let Inst{16-20} = ra;
190 let Inst{21-31} = flags;
191 }
192
193 class TBRI op, bits<5> br, dag outs, dag ins,
194 string asmstr, list pattern, InstrItinClass itin> :
195 MBlazeInst
196 {
197 bits<16> imm16;
198
199 let opcode = op;
200
201 let Inst{6-10} = 0;
202 let Inst{11-15} = br;
203 let Inst{16-31} = imm16;
204 }
205
206 class TBRLI op, bits<5> br, dag outs, dag ins,
207 string asmstr, list pattern, InstrItinClass itin> :
208 MBlazeInst
209 {
210 bits<16> imm16;
211
212 let opcode = op;
213
214 let Inst{6-10} = 0xF;
215 let Inst{11-15} = br;
216 let Inst{16-31} = imm16;
217 }
218
219 class TBRCI op, bits<5> br, dag outs, dag ins,
220 string asmstr, list pattern, InstrItinClass itin> :
221 MBlazeInst
222 {
223 bits<5> ra;
224 bits<16> imm16;
225
226 let opcode = op;
227
228 let Inst{6-10} = br;
229 let Inst{11-15} = ra;
230 let Inst{16-31} = imm16;
231 }
232
233 class TRET op, dag outs, dag ins,
234 string asmstr, list pattern, InstrItinClass itin> :
235 MBlazeInst
236 {
237 bits<5> ra;
238 bits<16> imm16;
239
240 let opcode = op;
241
242 let Inst{6-10} = 0x10;
243 let Inst{11-15} = ra;
244 let Inst{16-31} = imm16;
245 }
0 //===- MBlazeInstrInfo.cpp - MBlaze Instruction Information -----*- 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 MBlaze implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "MBlazeInstrInfo.h"
14 #include "MBlazeTargetMachine.h"
15 #include "MBlazeMachineFunction.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/CodeGen/MachineInstrBuilder.h"
18 #include "llvm/CodeGen/MachineRegisterInfo.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "MBlazeGenInstrInfo.inc"
21
22 using namespace llvm;
23
24 MBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm)
25 : TargetInstrInfoImpl(MBlazeInsts, array_lengthof(MBlazeInsts)),
26 TM(tm), RI(*TM.getSubtargetImpl(), *this) {}
27
28 static bool isZeroImm(const MachineOperand &op) {
29 return op.isImm() && op.getImm() == 0;
30 }
31
32 /// Return true if the instruction is a register to register move and
33 /// leave the source and dest operands in the passed parameters.
34 bool MBlazeInstrInfo::
35 isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg,
36 unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
37 SrcSubIdx = DstSubIdx = 0; // No sub-registers.
38
39 // add $dst, $src, $zero || addu $dst, $zero, $src
40 // or $dst, $src, $zero || or $dst, $zero, $src
41 if ((MI.getOpcode() == MBlaze::ADD) || (MI.getOpcode() == MBlaze::OR)) {
42 if (MI.getOperand(1).isReg() && MI.getOperand(1).getReg() == MBlaze::R0) {
43 DstReg = MI.getOperand(0).getReg();
44 SrcReg = MI.getOperand(2).getReg();
45 return true;
46 } else if (MI.getOperand(2).isReg() &&
47 MI.getOperand(2).getReg() == MBlaze::R0) {
48 DstReg = MI.getOperand(0).getReg();
49 SrcReg = MI.getOperand(1).getReg();
50 return true;
51 }
52 }
53
54 // addi $dst, $src, 0
55 // ori $dst, $src, 0
56 if ((MI.getOpcode() == MBlaze::ADDI) || (MI.getOpcode() == MBlaze::ORI)) {
57 if ((MI.getOperand(1).isReg()) && (isZeroImm(MI.getOperand(2)))) {
58 DstReg = MI.getOperand(0).getReg();
59 SrcReg = MI.getOperand(1).getReg();
60 return true;
61 }
62 }
63
64 return false;
65 }
66
67 /// isLoadFromStackSlot - If the specified machine instruction is a direct
68 /// load from a stack slot, return the virtual or physical register number of
69 /// the destination along with the FrameIndex of the loaded stack slot. If
70 /// not, return 0. This predicate must return 0 if the instruction has
71 /// any side effects other than loading from the stack slot.
72 unsigned MBlazeInstrInfo::
73 isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const {
74 if (MI->getOpcode() == MBlaze::LWI) {
75 if ((MI->getOperand(2).isFI()) && // is a stack slot
76 (MI->getOperand(1).isImm()) && // the imm is zero
77 (isZeroImm(MI->getOperand(1)))) {
78 FrameIndex = MI->getOperand(2).getIndex();
79 return MI->getOperand(0).getReg();
80 }
81 }
82
83 return 0;
84 }
85
86 /// isStoreToStackSlot - If the specified machine instruction is a direct
87 /// store to a stack slot, return the virtual or physical register number of
88 /// the source reg along with the FrameIndex of the loaded stack slot. If
89 /// not, return 0. This predicate must return 0 if the instruction has
90 /// any side effects other than storing to the stack slot.
91 unsigned MBlazeInstrInfo::
92 isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const {
93 if (MI->getOpcode() == MBlaze::SWI) {
94 if ((MI->getOperand(2).isFI()) && // is a stack slot
95 (MI->getOperand(1).isImm()) && // the imm is zero
96 (isZeroImm(MI->getOperand(1)))) {
97 FrameIndex = MI->getOperand(2).getIndex();
98 return MI->getOperand(0).getReg();
99 }
100 }
101 return 0;
102 }
103
104 /// insertNoop - If data hazard condition is found insert the target nop
105 /// instruction.
106 void MBlazeInstrInfo::
107 insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const {
108 DebugLoc DL = DebugLoc::getUnknownLoc();
109 if (MI != MBB.end()) DL = MI->getDebugLoc();
110 BuildMI(MBB, MI, DL, get(MBlaze::NOP));
111 }
112
113 bool MBlazeInstrInfo::
114 copyRegToReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
115 unsigned DestReg, unsigned SrcReg,
116 const TargetRegisterClass *DestRC,
117 const TargetRegisterClass *SrcRC) const {
118 DebugLoc dl = DebugLoc::getUnknownLoc();
119 llvm::BuildMI(MBB, I, dl, get(MBlaze::ADD), DestReg)
120 .addReg(SrcReg).addReg(MBlaze::R0);
121 return true;
122 }
123
124 void MBlazeInstrInfo::
125 storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
126 unsigned SrcReg, bool isKill, int FI,
127 const TargetRegisterClass *RC) const {
128 DebugLoc dl = DebugLoc::getUnknownLoc();
129 BuildMI(MBB, I, dl, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill))
130 .addImm(0).addFrameIndex(FI);
131 }
132
133 void MBlazeInstrInfo::
134 loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
135 unsigned DestReg, int FI,
136 const TargetRegisterClass *RC) const {
137 DebugLoc dl = DebugLoc::getUnknownLoc();
138 BuildMI(MBB, I, dl, get(MBlaze::LWI), DestReg)
139 .addImm(0).addFrameIndex(FI);
140 }
141
142 MachineInstr *MBlazeInstrInfo::
143 foldMemoryOperandImpl(MachineFunction &MF,
144 MachineInstr* MI,
145 const SmallVectorImpl &Ops, int FI) const {
146 if (Ops.size() != 1) return NULL;
147
148 MachineInstr *NewMI = NULL;
149
150 switch (MI->getOpcode()) {
151 case MBlaze::OR:
152 case MBlaze::ADD:
153 if ((MI->getOperand(0).isReg()) &&
154 (MI->getOperand(2).isReg()) &&
155 (MI->getOperand(2).getReg() == MBlaze::R0) &&
156 (MI->getOperand(1).isReg())) {
157 if (Ops[0] == 0) { // COPY -> STORE
158 unsigned SrcReg = MI->getOperand(1).getReg();
159 bool isKill = MI->getOperand(1).isKill();
160 bool isUndef = MI->getOperand(1).isUndef();
161 NewMI = BuildMI(MF, MI->getDebugLoc(), get(MBlaze::SW))
162 .addReg(SrcReg, getKillRegState(isKill) | getUndefRegState(isUndef))
163 .addImm(0).addFrameIndex(FI);
164 } else { // COPY -> LOAD
165 unsigned DstReg = MI->getOperand(0).getReg();
166 bool isDead = MI->getOperand(0).isDead();
167 bool isUndef = MI->getOperand(0).isUndef();
168 NewMI = BuildMI(MF, MI->getDebugLoc(), get(MBlaze::LW))
169 .addReg(DstReg, RegState::Define | getDeadRegState(isDead) |
170 getUndefRegState(isUndef))
171 .addImm(0).addFrameIndex(FI);
172 }
173 }
174 break;
175 }
176
177 return NewMI;
178 }
179
180 //===----------------------------------------------------------------------===//
181 // Branch Analysis
182 //===----------------------------------------------------------------------===//
183 unsigned MBlazeInstrInfo::
184 InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
185 MachineBasicBlock *FBB,
186 const SmallVectorImpl &Cond) const {
187 DebugLoc dl = DebugLoc::getUnknownLoc();
188
189 // Can only insert uncond branches so far.
190 assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
191 BuildMI(&MBB, dl, get(MBlaze::BRI)).addMBB(TBB);
192 return 1;
193 }
194
195 /// getGlobalBaseReg - Return a virtual register initialized with the
196 /// the global base register value. Output instructions required to
197 /// initialize the register in the function entry block, if necessary.
198 ///
199 unsigned MBlazeInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
200 MBlazeFunctionInfo *MBlazeFI = MF->getInfo();
201 unsigned GlobalBaseReg = MBlazeFI->getGlobalBaseReg();
202 if (GlobalBaseReg != 0)
203 return GlobalBaseReg;
204
205 // Insert the set of GlobalBaseReg into the first MBB of the function
206 MachineBasicBlock &FirstMBB = MF->front();
207 MachineBasicBlock::iterator MBBI = FirstMBB.begin();
208 MachineRegisterInfo &RegInfo = MF->getRegInfo();
209 const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
210
211 GlobalBaseReg = RegInfo.createVirtualRegister(MBlaze::CPURegsRegisterClass);
212 bool Ok = TII->copyRegToReg(FirstMBB, MBBI, GlobalBaseReg, MBlaze::R20,
213 MBlaze::CPURegsRegisterClass,
214 MBlaze::CPURegsRegisterClass);
215 assert(Ok && "Couldn't assign to global base register!");
216 Ok = Ok; // Silence warning when assertions are turned off.
217 RegInfo.addLiveIn(MBlaze::R20);
218
219 MBlazeFI->setGlobalBaseReg(GlobalBaseReg);
220 return GlobalBaseReg;
221 }
0 //===- MBlazeInstrInfo.h - MBlaze Instruction Information -------*- 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 MBlaze implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef MBLAZEINSTRUCTIONINFO_H
14 #define MBLAZEINSTRUCTIONINFO_H
15
16 #include "MBlaze.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include "llvm/Target/TargetInstrInfo.h"
19 #include "MBlazeRegisterInfo.h"
20
21 namespace llvm {
22
23 namespace MBlaze {
24
25 // MBlaze Branch Codes
26 enum FPBranchCode {
27 BRANCH_F,
28 BRANCH_T,
29 BRANCH_FL,
30 BRANCH_TL,
31 BRANCH_INVALID
32 };
33
34 // MBlaze Condition Codes
35 enum CondCode {
36 // To be used with float branch True
37 FCOND_F,
38 FCOND_UN,
39 FCOND_EQ,
40 FCOND_UEQ,
41 FCOND_OLT,
42 FCOND_ULT,
43 FCOND_OLE,
44 FCOND_ULE,
45 FCOND_SF,
46 FCOND_NGLE,
47 FCOND_SEQ,
48 FCOND_NGL,
49 FCOND_LT,
50 FCOND_NGE,
51 FCOND_LE,
52 FCOND_NGT,
53
54 // To be used with float branch False
55 // This conditions have the same mnemonic as the
56 // above ones, but are used with a branch False;
57 FCOND_T,
58 FCOND_OR,
59 FCOND_NEQ,
60 FCOND_OGL,
61 FCOND_UGE,
62 FCOND_OGE,
63 FCOND_UGT,
64 FCOND_OGT,
65 FCOND_ST,
66 FCOND_GLE,
67 FCOND_SNE,
68 FCOND_GL,
69 FCOND_NLT,
70 FCOND_GE,
71 FCOND_NLE,
72 FCOND_GT,
73
74 // Only integer conditions
75 COND_E,
76 COND_GZ,
77 COND_GEZ,
78 COND_LZ,
79 COND_LEZ,
80 COND_NE,
81 COND_INVALID
82 };
83
84 // Turn condition code into conditional branch opcode.
85 unsigned GetCondBranchFromCond(CondCode CC);
86
87 /// GetOppositeBranchCondition - Return the inverse of the specified cond,
88 /// e.g. turning COND_E to COND_NE.
89 CondCode GetOppositeBranchCondition(MBlaze::CondCode CC);
90
91 /// MBlazeCCToString - Map each FP condition code to its string
92 inline static const char *MBlazeFCCToString(MBlaze::CondCode CC)
93 {
94 switch (CC) {
95 default: llvm_unreachable("Unknown condition code");
96 case FCOND_F:
97 case FCOND_T: return "f";
98 case FCOND_UN:
99 case FCOND_OR: return "un";
100 case FCOND_EQ:
101 case FCOND_NEQ: return "eq";
102 case FCOND_UEQ:
103 case FCOND_OGL: return "ueq";
104 case FCOND_OLT:
105 case FCOND_UGE: return "olt";
106 case FCOND_ULT:
107 case FCOND_OGE: return "ult";
108 case FCOND_OLE:
109 case FCOND_UGT: return "ole";
110 case FCOND_ULE:
111 case FCOND_OGT: return "ule";
112 case FCOND_SF:
113 case FCOND_ST: return "sf";
114 case FCOND_NGLE:
115 case FCOND_GLE: return "ngle";
116 case FCOND_SEQ:
117 case FCOND_SNE: return "seq";
118 case FCOND_NGL:
119 case FCOND_GL: return "ngl";
120 case FCOND_LT:
121 case FCOND_NLT: return "lt";
122 case FCOND_NGE:
123 case FCOND_GE: return "ge";
124 case FCOND_LE:
125 case FCOND_NLE: return "nle";
126 case FCOND_NGT:
127 case FCOND_GT: return "gt";
128 }
129 }
130 }
131
132 /// MBlazeII - This namespace holds all of the target specific flags that
133 /// instruction info tracks.
134 ///
135 namespace MBlazeII {
136 /// Target Operand Flag enum.
137 enum TOF {
138 //===------------------------------------------------------------------===//
139 // MBlaze Specific MachineOperand flags.
140 MO_NO_FLAG,
141
142 /// MO_GOT - Represents the offset into the global offset table at which
143 /// the address the relocation entry symbol resides during execution.
144 MO_GOT,
145
146 /// MO_GOT_CALL - Represents the offset into the global offset table at
147 /// which the address of a call site relocation entry symbol resides
148 /// during execution. This is different from the above since this flag
149 /// can only be present in call instructions.
150 MO_GOT_CALL,
151
152 /// MO_GPREL - Represents the offset from the current gp value to be used
153 /// for the relocatable object file being produced.
154 MO_GPREL,
155
156 /// MO_ABS_HILO - Represents the hi or low part of an absolute symbol
157 /// address.
158 MO_ABS_HILO
159
160 };
161 }
162
163 class MBlazeInstrInfo : public TargetInstrInfoImpl {
164 MBlazeTargetMachine &TM;
165 const MBlazeRegisterInfo RI;
166 public:
167 explicit MBlazeInstrInfo(MBlazeTargetMachine &TM);
168
169 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
170 /// such, whenever a client has an instance of instruction info, it should
171 /// always be able to get register info as well (through this method).
172 ///
173 virtual const MBlazeRegisterInfo &getRegisterInfo() const { return RI; }
174
175 /// Return true if the instruction is a register to register move and return
176 /// the source and dest operands and their sub-register indices by reference.
177 virtual bool isMoveInstr(const MachineInstr &MI,
178 unsigned &SrcReg, unsigned &DstReg,
179 unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
180
181 /// isLoadFromStackSlot - If the specified machine instruction is a direct
182 /// load from a stack slot, return the virtual or physical register number of
183 /// the destination along with the FrameIndex of the loaded stack slot. If
184 /// not, return 0. This predicate must return 0 if the instruction has
185 /// any side effects other than loading from the stack slot.
186 virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
187 int &FrameIndex) const;
188
189 /// isStoreToStackSlot - If the specified machine instruction is a direct
190 /// store to a stack slot, return the virtual or physical register number of
191 /// the source reg along with the FrameIndex of the loaded stack slot. If
192 /// not, return 0. This predicate must return 0 if the instruction has
193 /// any side effects other than storing to the stack slot.
194 virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
195 int &FrameIndex) const;
196
197 /// Branch Analysis
198 virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
199 MachineBasicBlock *FBB,
200 const SmallVectorImpl &Cond) const;
201 virtual bool copyRegToReg(MachineBasicBlock &MBB,
202 MachineBasicBlock::iterator I,
203 unsigned DestReg, unsigned SrcReg,
204 const TargetRegisterClass *DestRC,
205 const TargetRegisterClass *SrcRC) const;
206 virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
207 MachineBasicBlock::iterator MBBI,
208 unsigned SrcReg, bool isKill, int FrameIndex,
209 const TargetRegisterClass *RC) const;
210
211 virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
212 MachineBasicBlock::iterator MBBI,
213 unsigned DestReg, int FrameIndex,
214 const TargetRegisterClass *RC) const;
215
216 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
217 MachineInstr* MI,
218 const SmallVectorImpl &Ops,
219 int FrameIndex) const;
220
221 virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
222 MachineInstr* MI,
223 const SmallVectorImpl &Ops,
224 MachineInstr* LoadMI) const {
225 return 0;
226 }
227
228 /// Insert nop instruction when hazard condition is found
229 virtual void insertNoop(MachineBasicBlock &MBB,
230 MachineBasicBlock::iterator MI) const;
231
232 /// getGlobalBaseReg - Return a virtual register initialized with the
233 /// the global base register value. Output instructions required to
234 /// initialize the register in the function entry block, if necessary.
235 ///
236 unsigned getGlobalBaseReg(MachineFunction *MF) const;
237 };
238
239 }
240
241 #endif
0 //===- MBlazeInstrInfo.td - MBlaze Instruction defs -------------*- 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 // Instruction format superclass
11 //===----------------------------------------------------------------------===//
12 include "MBlazeInstrFormats.td"
13
14 //===----------------------------------------------------------------------===//
15 // MBlaze profiles and nodes
16 //===----------------------------------------------------------------------===//
17 def SDT_MBlazeRet : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
18 def SDT_MBlazeJmpLink : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
19
20 // Call
21 def MBlazeJmpLink : SDNode<"MBlazeISD::JmpLink",SDT_MBlazeJmpLink,
22 [SDNPHasChain,SDNPOptInFlag,SDNPOutFlag]>;
23
24 // Return
25 def MBlazeRet : SDNode<"MBlazeISD::Ret", SDT_MBlazeRet,
26 [SDNPHasChain, SDNPOptInFlag]>;
27
28 // Hi and Lo nodes are used to handle global addresses. Used on
29 // MBlazeISelLowering to lower stuff like GlobalAddress, ExternalSymbol
30 // static model.
31 def MBWrapper : SDNode<"MBlazeISD::Wrap", SDTIntUnaryOp>;
32 def MBlazeGPRel : SDNode<"MBlazeISD::GPRel", SDTIntUnaryOp>;
33
34 def SDT_MBCallSeqStart : SDCallSeqStart<[SDTCisVT<0, i32>]>;
35 def SDT_MBCallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i32>, SDTCisVT<1, i32>]>;
36
37 // These are target-independent nodes, but have target-specific formats.
38 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_MBCallSeqStart,
39 [SDNPHasChain, SDNPOutFlag]>;
40 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_MBCallSeqEnd,
41 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
42
43 def SDTMBlazeSelectCC : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>]>;
44
45 //===----------------------------------------------------------------------===//
46 // MBlaze Instruction Predicate Definitions.
47 //===----------------------------------------------------------------------===//
48 def HasPipe3 : Predicate<"Subtarget.hasPipe3()">;
49 def HasBarrel : Predicate<"Subtarget.hasBarrel()">;
50 def NoBarrel : Predicate<"!Subtarget.hasBarrel()">;
51 def HasDiv : Predicate<"Subtarget.hasDiv()">;
52 def HasMul : Predicate<"Subtarget.hasMul()">;
53 def HasFSL : Predicate<"Subtarget.hasFSL()">;
54 def HasEFSL : Predicate<"Subtarget.hasEFSL()">;
55 def HasMSRSet : Predicate<"Subtarget.hasMSRSet()">;
56 def HasException : Predicate<"Subtarget.hasException()">;
57 def HasPatCmp : Predicate<"Subtarget.hasPatCmp()">;
58 def HasFPU : Predicate<"Subtarget.hasFPU()">;
59 def HasESR : Predicate<"Subtarget.hasESR()">;
60 def HasPVR : Predicate<"Subtarget.hasPVR()">;
61 def HasMul64 : Predicate<"Subtarget.hasMul64()">;
62 def HasSqrt : Predicate<"Subtarget.hasSqrt()">;
63 def HasMMU : Predicate<"Subtarget.hasMMU()">;
64
65 //===----------------------------------------------------------------------===//
66 // MBlaze Operand, Complex Patterns and Transformations Definitions.
67 //===----------------------------------------------------------------------===//
68
69 // Instruction operand types
70 def brtarget : Operand;
71 def calltarget : Operand;
72 def simm16 : Operand;
73 def uimm5 : Operand;
74 def fimm : Operand;
75
76 // Unsigned Operand
77 def uimm16 : Operand {
78 let PrintMethod = "printUnsignedImm";
79 }
80
81 // FSL Operand
82 def fslimm : Operand {
83 let PrintMethod = "printFSLImm";
84 }
85
86 // Address operand
87 def memri : Operand {
88 let PrintMethod = "printMemOperand";
89 let MIOperandInfo = (ops simm16, CPURegs);
90 }
91
92 def memrr : Operand {
93 let PrintMethod = "printMemOperand";
94 let MIOperandInfo = (ops CPURegs, CPURegs);
95 }
96
97 // Transformation Function - get the lower 16 bits.
98 def LO16 : SDNodeXForm
99 return getI32Imm((unsigned)N->getZExtValue() & 0xFFFF);
100 }]>;
101
102 // Transformation Function - get the higher 16 bits.
103 def HI16 : SDNodeXForm
104 return getI32Imm((unsigned)N->getZExtValue() >> 16);
105 }]>;
106
107 // Node immediate fits as 16-bit sign extended on target immediate.
108 // e.g. addi, andi
109 def immSExt16 : PatLeaf<(imm), [{
110 return (N->getZExtValue() >> 16) == 0;
111 }]>;
112
113 // Node immediate fits as 16-bit zero extended on target immediate.
114 // The LO16 param means that only the lower 16 bits of the node
115 // immediate are caught.
116 // e.g. addiu, sltiu
117 def immZExt16 : PatLeaf<(imm), [{
118 return (N->getZExtValue() >> 16) == 0;
119 }], LO16>;
120
121 // FSL immediate field must fit in 4 bits.
122 def immZExt4 : PatLeaf<(imm), [{
123 return N->getZExtValue() == ((N->getZExtValue()) & 0xf) ;
124 }]>;
125
126 // shamt field must fit in 5 bits.
127 def immZExt5 : PatLeaf<(imm), [{
128 return N->getZExtValue() == ((N->getZExtValue()) & 0x1f) ;
129 }]>;
130
131 // MBlaze Address Mode! SDNode frameindex could possibily be a match
132 // since load and store instructions from stack used it.
133 def iaddr : ComplexPattern;
134 def xaddr : ComplexPattern;
135
136 //===----------------------------------------------------------------------===//
137 // Pseudo instructions
138 //===----------------------------------------------------------------------===//
139
140 // As stack alignment is always done with addiu, we need a 16-bit immediate
141 let Defs = [R1], Uses = [R1] in {
142 def ADJCALLSTACKDOWN : MBlazePseudo<(outs), (ins simm16:$amt),
143 "${:comment} ADJCALLSTACKDOWN $amt",
144 [(callseq_start timm:$amt)]>;
145 def ADJCALLSTACKUP : MBlazePseudo<(outs),
146 (ins uimm16:$amt1, simm16:$amt2),
147 "${:comment} ADJCALLSTACKUP $amt1",
148 [(callseq_end timm:$amt1, timm:$amt2)]>;
149 }
150
151 // Some assembly macros need to avoid pseudoinstructions and assembler
152 // automatic reodering, we should reorder ourselves.
153 def MACRO : MBlazePseudo<(outs), (ins), ".set macro", []>;
154 def REORDER : MBlazePseudo<(outs), (ins), ".set reorder", []>;
155 def NOMACRO : MBlazePseudo<(outs), (ins), ".set nomacro", []>;
156 def NOREORDER : MBlazePseudo<(outs), (ins), ".set noreorder", []>;
157
158 // When handling PIC code the assembler needs .cpload and .cprestore
159 // directives. If the real instructions corresponding these directives
160 // are used, we have the same behavior, but get also a bunch of warnings
161 // from the assembler.
162 def CPLOAD : MBlazePseudo<(outs), (ins CPURegs:$reg), ".cpload $reg", []>;
163 def CPRESTORE : MBlazePseudo<(outs), (ins uimm16:$l), ".cprestore $l\n", []>;
164
165 //===----------------------------------------------------------------------===//
166 // Instructions specific format
167 //===----------------------------------------------------------------------===//
168
169 //===----------------------------------------------------------------------===//
170 // Arithmetic Instructions
171 //===----------------------------------------------------------------------===//
172 class Arith op, bits<11> flags, string instr_asm, SDNode OpNode,
173 InstrItinClass itin> :
174 TA
175 !strconcat(instr_asm, " $dst, $b, $c"),
176 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>;
177
178 class ArithI op, string instr_asm, SDNode OpNode,
179 Operand Od, PatLeaf imm_type> :
180 TAI
181 !strconcat(instr_asm, " $dst, $b, $c"),
182 [(set CPURegs:$dst, (OpNode CPURegs:$b, imm_type:$c))], IIAlu>;
183
184 class ArithR op, bits<11> flags, string instr_asm, SDNode OpNode,
185 InstrItinClass itin> :
186 TA
187 !strconcat(instr_asm, " $dst, $c, $b"),
188 [(set CPURegs:$dst, (OpNode CPURegs:$b, CPURegs:$c))], itin>;
189
190 class ArithRI op, string instr_asm, SDNode OpNode,
191 Operand Od, PatLeaf imm_type> :
192 TAI
193 !strconcat(instr_asm, " $dst, $c, $b"),
194 [(set CPURegs:$dst, (OpNode imm_type:$b, CPURegs:$c))], IIAlu>;
195
196 class ArithN op, bits<11> flags, string instr_asm,
197 InstrItinClass itin> :