llvm.org GIT mirror llvm / d2cb3d2
Remove the IA-64 backend. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@76920 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 10 years ago
53 changed file(s) with 13 addition(s) and 4544 deletion(s). Raw diff Collapse all Expand all
5151 CBackend
5252 CellSPU
5353 CppBackend
54 IA64
5554 Mips
5655 MSIL
5756 MSP430
254254 CF33BE160AF62B4200E93805 /* SmallString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SmallString.h; sourceTree = ""; };
255255 CF341DAD0AB07A8B0099B064 /* AlphaTargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlphaTargetAsmInfo.h; sourceTree = ""; };
256256 CF341DAE0AB07A8B0099B064 /* AlphaTargetAsmInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaTargetAsmInfo.cpp; sourceTree = ""; };
257 CF341DE80AB07F890099B064 /* IA64TargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IA64TargetAsmInfo.h; sourceTree = ""; };
258 CF341DE90AB07F890099B064 /* IA64TargetAsmInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IA64TargetAsmInfo.cpp; sourceTree = ""; };
259257 CF341E010AB080220099B064 /* PPCTargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PPCTargetAsmInfo.h; sourceTree = ""; };
260258 CF341E020AB080220099B064 /* PPCTargetAsmInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PPCTargetAsmInfo.cpp; sourceTree = ""; };
261259 CF341E220AB0814B0099B064 /* SparcTargetAsmInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SparcTargetAsmInfo.h; sourceTree = ""; };
314312 CF73C0AE098A51AD00627152 /* Alarm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Alarm.h; sourceTree = ""; };
315313 CF73C0AF098A51DD00627152 /* RSProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSProfiling.h; sourceTree = ""; };
316314 CF73C0B0098A523C00627152 /* ConstantFolding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ConstantFolding.cpp; sourceTree = ""; };
317 CF73C0B6098A53EF00627152 /* IA64Bundling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IA64Bundling.cpp; sourceTree = ""; };
318315 CF73C0B7098A546000627152 /* RSProfiling.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RSProfiling.cpp; sourceTree = ""; };
319316 CF73C0B8098A546000627152 /* RSProfiling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RSProfiling.h; sourceTree = ""; };
320317 CF73C0B9098A546000627152 /* Reg2Mem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Reg2Mem.cpp; sourceTree = ""; };
414411 CFA702C10A6FA85F0006009A /* AlphaGenRegisterInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenRegisterInfo.inc; sourceTree = ""; };
415412 CFA702C20A6FA85F0006009A /* AlphaGenRegisterNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenRegisterNames.inc; sourceTree = ""; };
416413 CFA702C30A6FA85F0006009A /* AlphaGenSubtarget.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = AlphaGenSubtarget.inc; sourceTree = ""; };
417 CFA702C40A6FA8910006009A /* IA64GenAsmWriter.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = IA64GenAsmWriter.inc; sourceTree = ""; };
418 CFA702C50A6FA8910006009A /* IA64GenDAGISel.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = IA64GenDAGISel.inc; sourceTree = ""; };
419 CFA702C60A6FA8910006009A /* IA64GenInstrInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = IA64GenInstrInfo.inc; sourceTree = ""; };
420 CFA702C70A6FA8910006009A /* IA64GenInstrNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = IA64GenInstrNames.inc; sourceTree = ""; };
421 CFA702C80A6FA8910006009A /* IA64GenRegisterInfo.h.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = IA64GenRegisterInfo.h.inc; sourceTree = ""; };
422 CFA702C90A6FA8910006009A /* IA64GenRegisterInfo.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = IA64GenRegisterInfo.inc; sourceTree = ""; };
423 CFA702CA0A6FA8910006009A /* IA64GenRegisterNames.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = IA64GenRegisterNames.inc; sourceTree = ""; };
424414 CFA702CB0A6FA8AD0006009A /* PPCGenAsmWriter.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = PPCGenAsmWriter.inc; sourceTree = ""; };
425415 CFA702CC0A6FA8AD0006009A /* PPCGenCodeEmitter.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; path = PPCGenCodeEmitter.inc; sourceTree = ""; };
426416 CFA702CD0A6FA8AD0006009A /* PPCGenDAGISel.inc */ = {isa = PBXFileReference; explicitFileType = sourcecode.pascal; fileEncoding = 4; path = PPCGenDAGISel.inc; sourceTree = ""; };
449439 CFC244BB0959F24C009F8C47 /* X86ISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = X86ISelDAGToDAG.cpp; sourceTree = ""; };
450440 CFC244BC0959F24C009F8C47 /* X86ISelLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = X86ISelLowering.cpp; sourceTree = ""; };
451441 CFC244BD0959F24C009F8C47 /* X86ISelLowering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = X86ISelLowering.h; sourceTree = ""; };
452 CFC244BF0959F2E3009F8C47 /* IA64ISelDAGToDAG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IA64ISelDAGToDAG.cpp; sourceTree = ""; };
453 CFC244C00959F2E3009F8C47 /* IA64ISelLowering.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IA64ISelLowering.cpp; sourceTree = ""; };
454 CFC244C10959F2E3009F8C47 /* IA64ISelLowering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IA64ISelLowering.h; sourceTree = ""; };
455442 CFD7E4F30A798FC3000C7379 /* LinkAllCodegenComponents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LinkAllCodegenComponents.h; sourceTree = ""; };
456443 CFD99AA80AFE827B0068D19C /* LICENSE.TXT */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE.TXT; path = ../LICENSE.TXT; sourceTree = SOURCE_ROOT; };
457444 CFD99AAD0AFE827B0068D19C /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.txt; path = ../README.txt; sourceTree = SOURCE_ROOT; };
681668 DE66EEAF08ABEE5E00323D32 /* AlphaTargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AlphaTargetMachine.cpp; sourceTree = ""; };
682669 DE66EEB008ABEE5E00323D32 /* AlphaTargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AlphaTargetMachine.h; sourceTree = ""; };
683670 DE66EECA08ABEE5E00323D32 /* CTargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CTargetMachine.h; sourceTree = ""; };
684 DE66EEF808ABEE5E00323D32 /* IA64.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IA64.h; sourceTree = ""; };
685 DE66EEF908ABEE5E00323D32 /* IA64.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = IA64.td; sourceTree = ""; };
686 DE66EEFA08ABEE5E00323D32 /* IA64AsmPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IA64AsmPrinter.cpp; sourceTree = ""; };
687 DE66EF0108ABEE5E00323D32 /* IA64InstrBuilder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IA64InstrBuilder.h; sourceTree = ""; };
688 DE66EF0208ABEE5E00323D32 /* IA64InstrFormats.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = IA64InstrFormats.td; sourceTree = ""; };
689 DE66EF0308ABEE5E00323D32 /* IA64InstrInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IA64InstrInfo.cpp; sourceTree = ""; };
690 DE66EF0408ABEE5E00323D32 /* IA64InstrInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IA64InstrInfo.h; sourceTree = ""; };
691 DE66EF0508ABEE5E00323D32 /* IA64InstrInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = IA64InstrInfo.td; sourceTree = ""; };
692 DE66EF0708ABEE5E00323D32 /* IA64MachineFunctionInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IA64MachineFunctionInfo.h; sourceTree = ""; };
693 DE66EF0808ABEE5E00323D32 /* IA64RegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IA64RegisterInfo.cpp; sourceTree = ""; };
694 DE66EF0908ABEE5E00323D32 /* IA64RegisterInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IA64RegisterInfo.h; sourceTree = ""; };
695 DE66EF0A08ABEE5E00323D32 /* IA64RegisterInfo.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = IA64RegisterInfo.td; sourceTree = ""; };
696 DE66EF0B08ABEE5E00323D32 /* IA64TargetMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = IA64TargetMachine.cpp; sourceTree = ""; };
697 DE66EF0C08ABEE5E00323D32 /* IA64TargetMachine.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = IA64TargetMachine.h; sourceTree = ""; };
698671 DE66EF0E08ABEE5E00323D32 /* README */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = README; sourceTree = ""; };
699672 DE66EF1008ABEE5E00323D32 /* TargetRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TargetRegisterInfo.cpp; sourceTree = ""; };
700673 DE66F08A08ABEE6000323D32 /* Target.td */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Target.td; sourceTree = ""; };
18291802 DE66EE9708ABEE5D00323D32 /* Alpha */,
18301803 CF8F1BCF0B64FC8A00BB4199 /* ARM */,
18311804 DE66EEC908ABEE5E00323D32 /* CBackend */,
1832 DE66EEE508ABEE5E00323D32 /* IA64 */,
18331805 9F7794120C73CB6100551F9C /* Mips */,
18341806 DE66EF1108ABEE5E00323D32 /* PowerPC */,
18351807 DE66EF7008ABEE5F00323D32 /* Sparc */,
19031875 DE66EECA08ABEE5E00323D32 /* CTargetMachine.h */,
19041876 );
19051877 path = CBackend;
1906 sourceTree = "";
1907 };
1908 DE66EEE508ABEE5E00323D32 /* IA64 */ = {
1909 isa = PBXGroup;
1910 children = (
1911 CFA702C40A6FA8910006009A /* IA64GenAsmWriter.inc */,
1912 CFA702C50A6FA8910006009A /* IA64GenDAGISel.inc */,
1913 CFA702C60A6FA8910006009A /* IA64GenInstrInfo.inc */,
1914 CFA702C70A6FA8910006009A /* IA64GenInstrNames.inc */,
1915 CFA702C80A6FA8910006009A /* IA64GenRegisterInfo.h.inc */,
1916 CFA702C90A6FA8910006009A /* IA64GenRegisterInfo.inc */,
1917 CFA702CA0A6FA8910006009A /* IA64GenRegisterNames.inc */,
1918 DE66EEF808ABEE5E00323D32 /* IA64.h */,
1919 DE66EEF908ABEE5E00323D32 /* IA64.td */,
1920 DE66EEFA08ABEE5E00323D32 /* IA64AsmPrinter.cpp */,
1921 CF73C0B6098A53EF00627152 /* IA64Bundling.cpp */,
1922 DE66EF0108ABEE5E00323D32 /* IA64InstrBuilder.h */,
1923 DE66EF0208ABEE5E00323D32 /* IA64InstrFormats.td */,
1924 DE66EF0308ABEE5E00323D32 /* IA64InstrInfo.cpp */,
1925 DE66EF0408ABEE5E00323D32 /* IA64InstrInfo.h */,
1926 DE66EF0508ABEE5E00323D32 /* IA64InstrInfo.td */,
1927 CFC244BF0959F2E3009F8C47 /* IA64ISelDAGToDAG.cpp */,
1928 CFC244C00959F2E3009F8C47 /* IA64ISelLowering.cpp */,
1929 CFC244C10959F2E3009F8C47 /* IA64ISelLowering.h */,
1930 DE66EF0708ABEE5E00323D32 /* IA64MachineFunctionInfo.h */,
1931 DE66EF0808ABEE5E00323D32 /* IA64RegisterInfo.cpp */,
1932 DE66EF0908ABEE5E00323D32 /* IA64RegisterInfo.h */,
1933 DE66EF0A08ABEE5E00323D32 /* IA64RegisterInfo.td */,
1934 CF341DE90AB07F890099B064 /* IA64TargetAsmInfo.cpp */,
1935 CF341DE80AB07F890099B064 /* IA64TargetAsmInfo.h */,
1936 DE66EF0B08ABEE5E00323D32 /* IA64TargetMachine.cpp */,
1937 DE66EF0C08ABEE5E00323D32 /* IA64TargetMachine.h */,
1938 DE66EF0E08ABEE5E00323D32 /* README */,
1939 );
1940 path = IA64;
19411878 sourceTree = "";
19421879 };
19431880 DE66EF1108ABEE5E00323D32 /* PowerPC */ = {
220220 sparc*-*) llvm_cv_target_arch="Sparc" ;;
221221 powerpc*-*) llvm_cv_target_arch="PowerPC" ;;
222222 alpha*-*) llvm_cv_target_arch="Alpha" ;;
223 ia64-*) llvm_cv_target_arch="IA64" ;;
224223 arm*-*) llvm_cv_target_arch="ARM" ;;
225224 mips-*) llvm_cv_target_arch="Mips" ;;
226225 pic16-*) llvm_cv_target_arch="PIC16" ;;
346345 PowerPC) AC_SUBST(TARGET_HAS_JIT,1) ;;
347346 x86_64) AC_SUBST(TARGET_HAS_JIT,1) ;;
348347 Alpha) AC_SUBST(TARGET_HAS_JIT,1) ;;
349 IA64) AC_SUBST(TARGET_HAS_JIT,0) ;;
350348 ARM) AC_SUBST(TARGET_HAS_JIT,0) ;;
351349 Mips) AC_SUBST(TARGET_HAS_JIT,0) ;;
352350 PIC16) AC_SUBST(TARGET_HAS_JIT,0) ;;
402400 [Build specific host targets: all,host-only,{target-name} (default=all)]),,
403401 enableval=all)
404402 case "$enableval" in
405 all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips CellSPU PIC16 XCore MSP430 SystemZ CBackend MSIL CppBackend" ;;
403 all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ CBackend MSIL CppBackend" ;;
406404 host-only)
407405 case "$llvm_cv_target_arch" in
408406 x86) TARGETS_TO_BUILD="X86" ;;
410408 Sparc) TARGETS_TO_BUILD="Sparc" ;;
411409 PowerPC) TARGETS_TO_BUILD="PowerPC" ;;
412410 Alpha) TARGETS_TO_BUILD="Alpha" ;;
413 IA64) TARGETS_TO_BUILD="IA64" ;;
414411 ARM) TARGETS_TO_BUILD="ARM" ;;
415412 Mips) TARGETS_TO_BUILD="Mips" ;;
416413 CellSPU|SPU) TARGETS_TO_BUILD="CellSPU" ;;
428425 sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
429426 powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
430427 alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
431 ia64) TARGETS_TO_BUILD="IA64 $TARGETS_TO_BUILD" ;;
432428 arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
433429 mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
434430 spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
100100 set(LLVM_NATIVE_ARCH PowerPC)
101101 elseif (LLVM_NATIVE_ARCH MATCHES "alpha")
102102 set(LLVM_NATIVE_ARCH Alpha)
103 elseif (LLVM_NATIVE_ARCH MATCHES "ia64")
104 set(LLVM_NATIVE_ARCH IA64)
105103 elseif (LLVM_NATIVE_ARCH MATCHES "arm")
106104 set(LLVM_NATIVE_ARCH ARM)
107105 elseif (LLVM_NATIVE_ARCH MATCHES "mips")
147147 set(MSVC_LIB_DEPS_LLVMCppBackendInfo LLVMSupport)
148148 set(MSVC_LIB_DEPS_LLVMDebugger LLVMAnalysis LLVMBitReader LLVMCore LLVMSupport LLVMSystem)
149149 set(MSVC_LIB_DEPS_LLVMExecutionEngine LLVMCore LLVMSupport LLVMSystem LLVMTarget)
150 set(MSVC_LIB_DEPS_LLVMIA64AsmPrinter LLVMAsmPrinter LLVMCodeGen LLVMCore LLVMIA64Info LLVMSupport LLVMSystem LLVMTarget)
151 set(MSVC_LIB_DEPS_LLVMIA64CodeGen LLVMCodeGen LLVMCore LLVMIA64Info LLVMSelectionDAG LLVMSupport LLVMSystem LLVMTarget)
152 set(MSVC_LIB_DEPS_LLVMIA64Info LLVMSupport)
153150 set(MSVC_LIB_DEPS_LLVMInstrumentation LLVMCore LLVMScalarOpts LLVMSupport LLVMSystem LLVMTransformUtils)
154151 set(MSVC_LIB_DEPS_LLVMInterpreter LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMSupport LLVMSystem LLVMTarget)
155152 set(MSVC_LIB_DEPS_LLVMJIT LLVMCodeGen LLVMCore LLVMExecutionEngine LLVMSupport LLVMSystem LLVMTarget)
23992399 sparc*-*) llvm_cv_target_arch="Sparc" ;;
24002400 powerpc*-*) llvm_cv_target_arch="PowerPC" ;;
24012401 alpha*-*) llvm_cv_target_arch="Alpha" ;;
2402 ia64-*) llvm_cv_target_arch="IA64" ;;
24032402 arm*-*) llvm_cv_target_arch="ARM" ;;
24042403 mips-*) llvm_cv_target_arch="Mips" ;;
24052404 pic16-*) llvm_cv_target_arch="PIC16" ;;
48424841 ;;
48434842 Alpha) TARGET_HAS_JIT=1
48444843 ;;
4845 IA64) TARGET_HAS_JIT=0
4846 ;;
48474844 ARM) TARGET_HAS_JIT=0
48484845 ;;
48494846 Mips) TARGET_HAS_JIT=0
49374934 fi
49384935
49394936 case "$enableval" in
4940 all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha IA64 ARM Mips CellSPU PIC16 XCore MSP430 SystemZ CBackend MSIL CppBackend" ;;
4937 all) TARGETS_TO_BUILD="X86 Sparc PowerPC Alpha ARM Mips CellSPU PIC16 XCore MSP430 SystemZ CBackend MSIL CppBackend" ;;
49414938 host-only)
49424939 case "$llvm_cv_target_arch" in
49434940 x86) TARGETS_TO_BUILD="X86" ;;
49454942 Sparc) TARGETS_TO_BUILD="Sparc" ;;
49464943 PowerPC) TARGETS_TO_BUILD="PowerPC" ;;
49474944 Alpha) TARGETS_TO_BUILD="Alpha" ;;
4948 IA64) TARGETS_TO_BUILD="IA64" ;;
49494945 ARM) TARGETS_TO_BUILD="ARM" ;;
49504946 Mips) TARGETS_TO_BUILD="Mips" ;;
49514947 CellSPU|SPU) TARGETS_TO_BUILD="CellSPU" ;;
49654961 sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
49664962 powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
49674963 alpha) TARGETS_TO_BUILD="Alpha $TARGETS_TO_BUILD" ;;
4968 ia64) TARGETS_TO_BUILD="IA64 $TARGETS_TO_BUILD" ;;
49694964 arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
49704965 mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
49714966 spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
13791379 for RegisterClass, the last parameter of which is a list of
13801380 registers. Just commenting some out is one simple way to avoid them being
13811381 used. A more polite way is to explicitly exclude some registers from
1382 the allocation order. See the definition of the GR register
1383 class in lib/Target/IA64/IA64RegisterInfo.td for an example of this
1384 (e.g., numReservedRegs registers are hidden.)

1382 the allocation order. See the definition of the GR8 register
1383 class in lib/Target/X86/X86RegisterInfo.td for an example of this.
1384

13851385
13861386

Virtual registers are also denoted by integer numbers. Contrary to physical

13871387 registers, different virtual registers never share the same number. The
490490 support is available for native builds with Visual C++).
491491
  • Sun UltraSPARC workstations running Solaris 10.
  • 492492
  • Alpha-based machines running Debian GNU/Linux.
  • 493
  • Itanium-based (IA64) machines running Linux and HP-UX.
  • 494493
    495494
    496495

    The core LLVM infrastructure uses GNU autoconf to adapt itself

    539538 href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev">LLVMdev list.

    540539
    541540
    542
  • The MSIL, IA64, Alpha, SPU, MIPS, and PIC16 backends are experimental.
  • 541
  • The MSIL, Alpha, SPU, MIPS, and PIC16 backends are experimental.
  • 543542
  • The llc "-filetype=asm" (the default) is the only
  • 544543 supported value for this option.
    545544
    649648 appropriate nops inserted to ensure restartability.
    650649
    651650
    652
    653
    654
    655
    656 Known problems with the IA64 back-end
    657
    658
    659
    660
    661
    662
  • The Itanium backend is highly experimental and has a number of known
  • 663 issues. We are looking for a maintainer for the Itanium backend. If you
    664 are interested, please contact the LLVMdev mailing list.
    665
    666
    667651
    668652
    669653
    127127 Code generation for ARM architecture
    128128
    LLVMCBackend.o
    129129 'C' language code generator.
    130
    LLVMIA64.o
    131 Code generation for IA64 architecture
    132130
    LLVMPowerPC.o
    133131 Code generation for PowerPC architecture
    134132
    LLVMSparc.o
    355353
  • libLLVMSystem.a
  • 356354
  • libLLVMTarget.a
  • 357355
    358
    LLVMIA64.o
    359
  • libLLVMCodeGen.a
  • 360
  • libLLVMCore.a
  • 361
  • libLLVMSelectionDAG.a
  • 362
  • libLLVMSupport.a
  • 363
  • libLLVMSystem.a
  • 364
  • libLLVMTarget.a
  • 365
    366356
    LLVMInterpreter.o
    367357
  • LLVMExecutionEngine.o
  • 368358
  • libLLVMCodeGen.a
  • 264264
    265265 /// FunctionAddrPrefix/Suffix - If these are nonempty, these strings
    266266 /// will enclose any GlobalVariable that points to a function.
    267 /// For example, this is used by the IA64 backend to materialize
    268 /// function descriptors, by decorating the ".data8" object with the
    269 /// @verbatim @fptr( ) @endverbatim
    270 /// link-relocation operator.
    271267 ///
    272268 const char *FunctionAddrPrefix; // Defaults to ""
    273269 const char *FunctionAddrSuffix; // Defaults to ""
    +0
    -9
    lib/Target/IA64/AsmPrinter/CMakeLists.txt less more
    None include_directories(
    1 ${CMAKE_CURRENT_BINARY_DIR}/..
    2 ${CMAKE_CURRENT_SOURCE_DIR}/..
    3 )
    4
    5 add_llvm_library(LLVMIA64AsmPrinter
    6 IA64AsmPrinter.cpp
    7 )
    8 add_dependencies(LLVMIA64AsmPrinter IA64CodeGenTable_gen)
    +0
    -377
    lib/Target/IA64/AsmPrinter/IA64AsmPrinter.cpp less more
    None //===-- IA64AsmPrinter.cpp - Print out IA64 LLVM as assembly --------------===//
    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 assembly accepted by the GNU binutils 'gas'
    11 // assembler. The Intel 'ias' and HP-UX 'as' assemblers *may* choke on this
    12 // output, but if so that's a bug I'd like to hear about: please file a bug
    13 // report in bugzilla. FYI, the not too bad 'ias' assembler is bundled with
    14 // the Intel C/C++ compiler for Itanium Linux.
    15 //
    16 //===----------------------------------------------------------------------===//
    17
    18 #define DEBUG_TYPE "asm-printer"
    19 #include "IA64.h"
    20 #include "IA64TargetMachine.h"
    21 #include "llvm/Module.h"
    22 #include "llvm/MDNode.h"
    23 #include "llvm/Type.h"
    24 #include "llvm/CodeGen/AsmPrinter.h"
    25 #include "llvm/CodeGen/DwarfWriter.h"
    26 #include "llvm/CodeGen/MachineFunctionPass.h"
    27 #include "llvm/Target/TargetAsmInfo.h"
    28 #include "llvm/Target/TargetRegistry.h"
    29 #include "llvm/Support/ErrorHandling.h"
    30 #include "llvm/Support/FormattedStream.h"
    31 #include "llvm/Support/Mangler.h"
    32 #include "llvm/ADT/Statistic.h"
    33 using namespace llvm;
    34
    35 STATISTIC(EmittedInsts, "Number of machine instrs printed");
    36
    37 namespace {
    38 class IA64AsmPrinter : public AsmPrinter {
    39 std::set ExternalFunctionNames, ExternalObjectNames;
    40 public:
    41 explicit IA64AsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
    42 const TargetAsmInfo *T, bool V)
    43 : AsmPrinter(O, TM, T, V) {}
    44
    45 virtual const char *getPassName() const {
    46 return "IA64 Assembly Printer";
    47 }
    48
    49 /// printInstruction - This method is automatically generated by tablegen
    50 /// from the instruction set description. This method returns true if the
    51 /// machine instruction was sufficiently described to print it, otherwise it
    52 /// returns false.
    53 bool printInstruction(const MachineInstr *MI);
    54
    55 // This method is used by the tablegen'erated instruction printer.
    56 void printOperand(const MachineInstr *MI, unsigned OpNo){
    57 const MachineOperand &MO = MI->getOperand(OpNo);
    58 if (MO.getType() == MachineOperand::MO_Register) {
    59 assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
    60 "Not physref??");
    61 //XXX Bug Workaround: See note in Printer::doInitialization about %.
    62 O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
    63 } else {
    64 printOp(MO);
    65 }
    66 }
    67
    68 void printS8ImmOperand(const MachineInstr *MI, unsigned OpNo) {
    69 int val=(unsigned int)MI->getOperand(OpNo).getImm();
    70 if(val>=128) val=val-256; // if negative, flip sign
    71 O << val;
    72 }
    73 void printS14ImmOperand(const MachineInstr *MI, unsigned OpNo) {
    74 int val=(unsigned int)MI->getOperand(OpNo).getImm();
    75 if(val>=8192) val=val-16384; // if negative, flip sign
    76 O << val;
    77 }
    78 void printS22ImmOperand(const MachineInstr *MI, unsigned OpNo) {
    79 int val=(unsigned int)MI->getOperand(OpNo).getImm();
    80 if(val>=2097152) val=val-4194304; // if negative, flip sign
    81 O << val;
    82 }
    83 void printU64ImmOperand(const MachineInstr *MI, unsigned OpNo) {
    84 O << (uint64_t)MI->getOperand(OpNo).getImm();
    85 }
    86 void printS64ImmOperand(const MachineInstr *MI, unsigned OpNo) {
    87 // XXX : nasty hack to avoid GPREL22 "relocation truncated to fit" linker
    88 // errors - instead of add rX = @gprel(CPI), r1;; we now
    89 // emit movl rX = @gprel(CPI
    90 // add rX = rX, r1;
    91 // this gives us 64 bits instead of 22 (for the add long imm) to play
    92 // with, which shuts up the linker. The problem is that the constant
    93 // pool entries aren't immediates at this stage, so we check here.
    94 // If it's an immediate, print it the old fashioned way. If it's
    95 // not, we print it as a constant pool index.
    96 if (MI->getOperand(OpNo).isImm()) {
    97 O << (int64_t)MI->getOperand(OpNo).getImm();
    98 } else { // this is a constant pool reference: FIXME: assert this
    99 printOp(MI->getOperand(OpNo));
    100 }
    101 }
    102
    103 void printGlobalOperand(const MachineInstr *MI, unsigned OpNo) {
    104 printOp(MI->getOperand(OpNo), false); // this is NOT a br.call instruction
    105 }
    106
    107 void printCallOperand(const MachineInstr *MI, unsigned OpNo) {
    108 printOp(MI->getOperand(OpNo), true); // this is a br.call instruction
    109 }
    110
    111 void printMachineInstruction(const MachineInstr *MI);
    112 void printOp(const MachineOperand &MO, bool isBRCALLinsn= false);
    113 void PrintGlobalVariable(const GlobalVariable *GVar);
    114 bool runOnMachineFunction(MachineFunction &F);
    115 bool doInitialization(Module &M);
    116 bool doFinalization(Module &M);
    117 };
    118 } // end of anonymous namespace
    119
    120
    121 // Include the auto-generated portion of the assembly writer.
    122 #include "IA64GenAsmWriter.inc"
    123
    124 /// runOnMachineFunction - This uses the printMachineInstruction()
    125 /// method to print assembly for each instruction.
    126 ///
    127 bool IA64AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
    128 this->MF = &MF;
    129
    130 SetupMachineFunction(MF);
    131 O << "\n\n";
    132
    133 // Print out constants referenced by the function
    134 EmitConstantPool(MF.getConstantPool());
    135
    136 const Function *F = MF.getFunction();
    137 SwitchToSection(TAI->SectionForGlobal(F));
    138
    139 // Print out labels for the function.
    140 EmitAlignment(MF.getAlignment());
    141 O << "\t.global\t" << CurrentFnName << '\n';
    142
    143 printVisibility(CurrentFnName, F->getVisibility());
    144
    145 O << "\t.type\t" << CurrentFnName << ", @function\n";
    146 O << CurrentFnName << ":\n";
    147
    148 // Print out code for the function.
    149 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
    150 I != E; ++I) {
    151 // Print a label for the basic block if there are any predecessors.
    152 if (!I->pred_empty()) {
    153 printBasicBlockLabel(I, true, true);
    154 O << '\n';
    155 }
    156 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
    157 II != E; ++II) {
    158 // Print the assembly for the instruction.
    159 printMachineInstruction(II);
    160 }
    161 }
    162
    163 // We didn't modify anything.
    164 return false;
    165 }
    166
    167 void IA64AsmPrinter::printOp(const MachineOperand &MO,
    168 bool isBRCALLinsn /* = false */) {
    169 const TargetRegisterInfo &RI = *TM.getRegisterInfo();
    170 switch (MO.getType()) {
    171 case MachineOperand::MO_Register:
    172 O << RI.get(MO.getReg()).AsmName;
    173 return;
    174
    175 case MachineOperand::MO_Immediate:
    176 O << MO.getImm();
    177 return;
    178 case MachineOperand::MO_MachineBasicBlock:
    179 printBasicBlockLabel(MO.getMBB());
    180 return;
    181 case MachineOperand::MO_ConstantPoolIndex: {
    182 O << "@gprel(" << TAI->getPrivateGlobalPrefix()
    183 << "CPI" << getFunctionNumber() << "_" << MO.getIndex() << ")";
    184 return;
    185 }
    186
    187 case MachineOperand::MO_GlobalAddress: {
    188
    189 // functions need @ltoff(@fptr(fn_name)) form
    190 GlobalValue *GV = MO.getGlobal();
    191 Function *F = dyn_cast(GV);
    192
    193 bool Needfptr=false; // if we're computing an address @ltoff(X), do
    194 // we need to decorate it so it becomes
    195 // @ltoff(@fptr(X)) ?
    196 if (F && !isBRCALLinsn /*&& F->isDeclaration()*/)
    197 Needfptr=true;
    198
    199 // if this is the target of a call instruction, we should define
    200 // the function somewhere (GNU gas has no problem without this, but
    201 // Intel ias rightly complains of an 'undefined symbol')
    202
    203 if (F /*&& isBRCALLinsn*/ && F->isDeclaration())
    204 ExternalFunctionNames.insert(Mang->getMangledName(MO.getGlobal()));
    205 else
    206 if (GV->isDeclaration()) // e.g. stuff like 'stdin'
    207 ExternalObjectNames.insert(Mang->getMangledName(MO.getGlobal()));
    208
    209 if (!isBRCALLinsn)
    210 O << "@ltoff(";
    211 if (Needfptr)
    212 O << "@fptr(";
    213 O << Mang->getMangledName(MO.getGlobal());
    214
    215 if (Needfptr && !isBRCALLinsn)
    216 O << "#))"; // close both fptr( and ltoff(
    217 else {
    218 if (Needfptr)
    219 O << "#)"; // close only fptr(
    220 if (!isBRCALLinsn)
    221 O << "#)"; // close only ltoff(
    222 }
    223
    224 int Offset = MO.getOffset();
    225 if (Offset > 0)
    226 O << " + " << Offset;
    227 else if (Offset < 0)
    228 O << " - " << -Offset;
    229 return;
    230 }
    231 case MachineOperand::MO_ExternalSymbol:
    232 O << MO.getSymbolName();
    233 ExternalFunctionNames.insert(MO.getSymbolName());
    234 return;
    235 default:
    236 O << ""; return;
    237 }
    238 }
    239
    240 /// printMachineInstruction -- Print out a single IA64 LLVM instruction
    241 /// MI to the current output stream.
    242 ///
    243 void IA64AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
    244 ++EmittedInsts;
    245
    246 // Call the autogenerated instruction printer routines.
    247 printInstruction(MI);
    248 }
    249
    250 bool IA64AsmPrinter::doInitialization(Module &M) {
    251 bool Result = AsmPrinter::doInitialization(M);
    252
    253 O << "\n.ident \"LLVM-ia64\"\n\n"
    254 << "\t.psr lsb\n" // should be "msb" on HP-UX, for starters
    255 << "\t.radix C\n"
    256 << "\t.psr abi64\n"; // we only support 64 bits for now
    257 return Result;
    258 }
    259
    260 void IA64AsmPrinter::PrintGlobalVariable(const GlobalVariable *GVar) {
    261 const TargetData *TD = TM.getTargetData();
    262
    263 if (!GVar->hasInitializer())
    264 return; // External global require no code
    265
    266 // Check to see if this is a special global used by LLVM, if so, emit it.
    267 if (EmitSpecialLLVMGlobal(GVar))
    268 return;
    269
    270 O << "\n\n";
    271 std::string name = Mang->getMangledName(GVar);
    272 Constant *C = GVar->getInitializer();
    273 if (isa(C) || isa(C))
    274 return;
    275 unsigned Size = TD->getTypeAllocSize(C->getType());
    276 unsigned Align = TD->getPreferredAlignmentLog(GVar);
    277
    278 printVisibility(name, GVar->getVisibility());
    279
    280 SwitchToSection(TAI->SectionForGlobal(GVar));
    281
    282 if (C->isNullValue() && !GVar->hasSection()) {
    283 if (!GVar->isThreadLocal() &&
    284 (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
    285 if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
    286
    287 if (GVar->hasLocalLinkage()) {
    288 O << "\t.lcomm " << name << "#," << Size
    289 << ',' << (1 << Align);
    290 O << '\n';
    291 } else {
    292 O << "\t.common " << name << "#," << Size
    293 << ',' << (1 << Align);
    294 O << '\n';
    295 }
    296
    297 return;
    298 }
    299 }
    300
    301 switch (GVar->getLinkage()) {
    302 case GlobalValue::LinkOnceAnyLinkage:
    303 case GlobalValue::LinkOnceODRLinkage:
    304 case GlobalValue::CommonLinkage:
    305 case GlobalValue::WeakAnyLinkage:
    306 case GlobalValue::WeakODRLinkage:
    307 // Nonnull linkonce -> weak
    308 O << "\t.weak " << name << '\n';
    309 break;
    310 case GlobalValue::AppendingLinkage:
    311 // FIXME: appending linkage variables should go into a section of
    312 // their name or something. For now, just emit them as external.
    313 case GlobalValue::ExternalLinkage:
    314 // If external or appending, declare as a global symbol
    315 O << TAI->getGlobalDirective() << name << '\n';
    316 // FALL THROUGH
    317 case GlobalValue::InternalLinkage:
    318 case GlobalValue::PrivateLinkage:
    319 case GlobalValue::LinkerPrivateLinkage:
    320 break;
    321 case GlobalValue::GhostLinkage:
    322 llvm_unreachable("GhostLinkage cannot appear in IA64AsmPrinter!");
    323 case GlobalValue::DLLImportLinkage:
    324 llvm_unreachable("DLLImport linkage is not supported by this target!");
    325 case GlobalValue::DLLExportLinkage:
    326 llvm_unreachable("DLLExport linkage is not supported by this target!");
    327 default:
    328 llvm_unreachable("Unknown linkage type!");
    329 }
    330
    331 EmitAlignment(Align, GVar);
    332
    333 if (TAI->hasDotTypeDotSizeDirective()) {
    334 O << "\t.type " << name << ",@object\n";
    335 O << "\t.size " << name << ',' << Size << '\n';
    336 }
    337
    338 O << name << ":\n";
    339 EmitGlobalConstant(C);
    340 }
    341
    342
    343 bool IA64AsmPrinter::doFinalization(Module &M) {
    344 // we print out ".global X \n .type X, @function" for each external function
    345 O << "\n\n// br.call targets referenced (and not defined) above: \n";
    346 for (std::set::iterator i = ExternalFunctionNames.begin(),
    347 e = ExternalFunctionNames.end(); i!=e; ++i) {
    348 O << "\t.global " << *i << "\n\t.type " << *i << ", @function\n";
    349 }
    350 O << "\n\n";
    351
    352 // we print out ".global X \n .type X, @object" for each external object
    353 O << "\n\n// (external) symbols referenced (and not defined) above: \n";
    354 for (std::set::iterator i = ExternalObjectNames.begin(),
    355 e = ExternalObjectNames.end(); i!=e; ++i) {
    356 O << "\t.global " << *i << "\n\t.type " << *i << ", @object\n";
    357 }
    358 O << "\n\n";
    359
    360 return AsmPrinter::doFinalization(M);
    361 }
    362
    363 /// createIA64CodePrinterPass - Returns a pass that prints the IA64
    364 /// assembly code for a MachineFunction to the given output stream, using
    365 /// the given target machine description.
    366 ///
    367 FunctionPass *llvm::createIA64CodePrinterPass(formatted_raw_ostream &o,
    368 TargetMachine &tm,
    369 bool verbose) {
    370 return new IA64AsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose);
    371 }
    372
    373 // Force static initialization.
    374 extern "C" void LLVMInitializeIA64AsmPrinter() {
    375 TargetRegistry::RegisterAsmPrinter(TheIA64Target, createIA64CodePrinterPass);
    376 }
    +0
    -17
    lib/Target/IA64/AsmPrinter/Makefile less more
    None ##===- lib/Target/IA64/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 = LLVMIA64AsmPrinter
    11
    12 # Hack: we need to include 'main' IA64 target directory to grab
    13 # private headers
    14 CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
    15
    16 include $(LEVEL)/Makefile.common
    +0
    -22
    lib/Target/IA64/CMakeLists.txt less more
    None set(LLVM_TARGET_DEFINITIONS IA64.td)
    1
    2 tablegen(IA64GenRegisterInfo.h.inc -gen-register-desc-header)
    3 tablegen(IA64GenRegisterNames.inc -gen-register-enums)
    4 tablegen(IA64GenRegisterInfo.inc -gen-register-desc)
    5 tablegen(IA64GenInstrNames.inc -gen-instr-enums)
    6 tablegen(IA64GenInstrInfo.inc -gen-instr-desc)
    7 tablegen(IA64GenAsmWriter.inc -gen-asm-writer)
    8 tablegen(IA64GenDAGISel.inc -gen-dag-isel)
    9
    10 add_llvm_target(IA64CodeGen
    11 IA64Bundling.cpp
    12 IA64InstrInfo.cpp
    13 IA64ISelDAGToDAG.cpp
    14 IA64ISelLowering.cpp
    15 IA64RegisterInfo.cpp
    16 IA64Subtarget.cpp
    17 IA64TargetAsmInfo.cpp
    18 IA64TargetMachine.cpp
    19 )
    20
    21 target_link_libraries (LLVMIA64CodeGen LLVMSelectionDAG)
    +0
    -59
    lib/Target/IA64/IA64.h less more
    None //===-- IA64.h - Top-level interface for IA64 representation ------*- C++ -*-===//
    1 // The LLVM Compiler Infrastructure
    2 //
    3 // This file is distributed under the University of Illinois Open Source
    4 // License. See LICENSE.TXT for details.
    5 //
    6 //===----------------------------------------------------------------------===//
    7 //
    8 // This file contains the entry points for global functions defined in the IA64
    9 // target library, as used by the LLVM JIT.
    10 //
    11 //===----------------------------------------------------------------------===//
    12
    13 #ifndef TARGET_IA64_H
    14 #define TARGET_IA64_H
    15
    16 #include "llvm/Target/TargetMachine.h"
    17
    18 namespace llvm {
    19
    20 class IA64TargetMachine;
    21 class FunctionPass;
    22 class formatted_raw_ostream;
    23
    24 /// createIA64DAGToDAGInstructionSelector - This pass converts an LLVM
    25 /// function into IA64 machine code in a sane, DAG->DAG transform.
    26 ///
    27 FunctionPass *createIA64DAGToDAGInstructionSelector(IA64TargetMachine &TM);
    28
    29 /// createIA64BundlingPass - This pass adds stop bits and bundles
    30 /// instructions.
    31 ///
    32 FunctionPass *createIA64BundlingPass(IA64TargetMachine &TM);
    33
    34 /// createIA64CodePrinterPass - Returns a pass that prints the IA64
    35 /// assembly code for a MachineFunction to the given output stream,
    36 /// using the given target machine description. This should work
    37 /// regardless of whether the function is in SSA form.
    38 ///
    39 FunctionPass *createIA64CodePrinterPass(formatted_raw_ostream &o,
    40 TargetMachine &tm,
    41 bool verbose);
    42
    43 extern Target TheIA64Target;
    44
    45 } // End llvm namespace
    46
    47 // Defines symbolic names for IA64 registers. This defines a mapping from
    48 // register name to register number.
    49 //
    50 #include "IA64GenRegisterNames.inc"
    51
    52 // Defines symbolic names for the IA64 instructions.
    53 //
    54 #include "IA64GenInstrNames.inc"
    55
    56 #endif
    57
    58
    +0
    -39
    lib/Target/IA64/IA64.td less more
    None //===-- IA64.td - Target definition file for Intel IA64 -------------------===//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // This is a target description file for the Intel IA64 architecture,
    10 // also known variously as ia64, IA-64, IPF, "the Itanium architecture" etc.
    11 //
    12 //===----------------------------------------------------------------------===//
    13
    14 // Get the target-independent interfaces which we are implementing...
    15 //
    16 include "llvm/Target/Target.td"
    17
    18 //===----------------------------------------------------------------------===//
    19 // Register File Description
    20 //===----------------------------------------------------------------------===//
    21
    22 include "IA64RegisterInfo.td"
    23
    24 //===----------------------------------------------------------------------===//
    25 // Instruction Descriptions
    26 //===----------------------------------------------------------------------===//
    27
    28 include "IA64InstrInfo.td"
    29
    30 def IA64InstrInfo : InstrInfo { }
    31
    32 def IA64 : Target {
    33 // Our instruction set
    34 let InstructionSet = IA64InstrInfo;
    35
    36 }
    37
    38
    +0
    -118
    lib/Target/IA64/IA64Bundling.cpp less more
    None //===-- IA64Bundling.cpp - IA-64 instruction bundling pass. ------------ --===//
    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 // Add stops where required to prevent read-after-write and write-after-write
    10 // dependencies, for both registers and memory addresses. There are exceptions:
    11 //
    12 // - Compare instructions (cmp*, tbit, tnat, fcmp, frcpa) are OK with
    13 // WAW dependencies so long as they all target p0, or are of parallel
    14 // type (.and*/.or*)
    15 //
    16 // FIXME: bundling, for now, is left to the assembler.
    17 // FIXME: this might be an appropriate place to translate between different
    18 // instructions that do the same thing, if this helps bundling.
    19 //
    20 //===----------------------------------------------------------------------===//
    21
    22 #define DEBUG_TYPE "ia64-codegen"
    23 #include "IA64.h"
    24 #include "IA64InstrInfo.h"
    25 #include "IA64TargetMachine.h"
    26 #include "llvm/CodeGen/MachineFunctionPass.h"
    27 #include "llvm/CodeGen/MachineInstrBuilder.h"
    28 #include "llvm/ADT/SetOperations.h"
    29 #include "llvm/ADT/Statistic.h"
    30 #include "llvm/Support/Debug.h"
    31 #include
    32 using namespace llvm;
    33
    34 STATISTIC(StopBitsAdded, "Number of stop bits added");
    35
    36 namespace {
    37 struct IA64BundlingPass : public MachineFunctionPass {
    38 static char ID;
    39 /// Target machine description which we query for reg. names, data
    40 /// layout, etc.
    41 ///
    42 IA64TargetMachine &TM;
    43
    44 IA64BundlingPass(IA64TargetMachine &tm)
    45 : MachineFunctionPass(&ID), TM(tm) { }
    46
    47 virtual const char *getPassName() const {
    48 return "IA64 (Itanium) Bundling Pass";
    49 }
    50
    51 bool runOnMachineBasicBlock(MachineBasicBlock &MBB);
    52 bool runOnMachineFunction(MachineFunction &F) {
    53 bool Changed = false;
    54 for (MachineFunction::iterator FI = F.begin(), FE = F.end();
    55 FI != FE; ++FI)
    56 Changed |= runOnMachineBasicBlock(*FI);
    57 return Changed;
    58 }
    59
    60 // XXX: ugly global, but pending writes can cross basic blocks. Note that
    61 // taken branches end instruction groups. So we only need to worry about
    62 // 'fallthrough' code
    63 std::set PendingRegWrites;
    64 };
    65 char IA64BundlingPass::ID = 0;
    66 } // end of anonymous namespace
    67
    68 /// createIA64BundlingPass - Returns a pass that adds STOP (;;) instructions
    69 /// and arranges the result into bundles.
    70 ///
    71 FunctionPass *llvm::createIA64BundlingPass(IA64TargetMachine &tm) {
    72 return new IA64BundlingPass(tm);
    73 }
    74
    75 /// runOnMachineBasicBlock - add stops and bundle this MBB.
    76 ///
    77 bool IA64BundlingPass::runOnMachineBasicBlock(MachineBasicBlock &MBB) {
    78 bool Changed = false;
    79
    80 for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) {
    81 MachineInstr *CurrentInsn = I++;
    82 std::set CurrentReads, CurrentWrites, OrigWrites;
    83
    84 for(unsigned i=0; i < CurrentInsn->getNumOperands(); i++) {
    85 MachineOperand &MO=CurrentInsn->getOperand(i);
    86 if (MO.isReg()) {
    87 if(MO.isUse()) { // TODO: exclude p0
    88 CurrentReads.insert(MO.getReg());
    89 }
    90 if(MO.isDef()) { // TODO: exclude p0
    91 CurrentWrites.insert(MO.getReg());
    92 OrigWrites.insert(MO.getReg()); // FIXME: use a nondestructive
    93 // set_intersect instead?
    94 }
    95 }
    96 }
    97
    98 // CurrentReads/CurrentWrites contain info for the current instruction.
    99 // Does it read or write any registers that are pending a write?
    100 // (i.e. not separated by a stop)
    101 set_intersect(CurrentReads, PendingRegWrites);
    102 set_intersect(CurrentWrites, PendingRegWrites);
    103
    104 if(! (CurrentReads.empty() && CurrentWrites.empty()) ) {
    105 // there is a conflict, insert a stop and reset PendingRegWrites
    106 CurrentInsn = BuildMI(MBB, CurrentInsn, CurrentInsn->getDebugLoc(),
    107 TM.getInstrInfo()->get(IA64::STOP), 0);
    108 PendingRegWrites=OrigWrites; // carry over current writes to next insn
    109 Changed=true; StopBitsAdded++; // update stats
    110 } else { // otherwise, track additional pending writes
    111 set_union(PendingRegWrites, OrigWrites);
    112 }
    113 } // onto the next insn in the MBB
    114
    115 return Changed;
    116 }
    117
    +0
    -577
    lib/Target/IA64/IA64ISelDAGToDAG.cpp less more
    None //===---- IA64ISelDAGToDAG.cpp - IA64 pattern matching inst selector ------===//
    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 a pattern matching instruction selector for IA64,
    10 // converting a legalized dag to an IA64 dag.
    11 //
    12 //===----------------------------------------------------------------------===//
    13
    14 #define DEBUG_TYPE "ia64-codegen"
    15 #include "IA64.h"
    16 #include "IA64TargetMachine.h"
    17 #include "IA64ISelLowering.h"
    18 #include "llvm/CodeGen/MachineInstrBuilder.h"
    19 #include "llvm/CodeGen/MachineFunction.h"
    20 #include "llvm/CodeGen/SelectionDAG.h"
    21 #include "llvm/CodeGen/SelectionDAGISel.h"
    22 #include "llvm/Target/TargetOptions.h"
    23 #include "llvm/Constants.h"
    24 #include "llvm/GlobalValue.h"
    25 #include "llvm/Intrinsics.h"
    26 #include "llvm/Support/Compiler.h"
    27 #include "llvm/Support/Debug.h"
    28 #include "llvm/Support/ErrorHandling.h"
    29 #include "llvm/Support/MathExtras.h"
    30 #include "llvm/Support/raw_ostream.h"
    31 using namespace llvm;
    32
    33 namespace {
    34 //===--------------------------------------------------------------------===//
    35 /// IA64DAGToDAGISel - IA64 specific code to select IA64 machine
    36 /// instructions for SelectionDAG operations.
    37 ///
    38 class IA64DAGToDAGISel : public SelectionDAGISel {
    39 unsigned GlobalBaseReg;
    40 public:
    41 explicit IA64DAGToDAGISel(IA64TargetMachine &TM)
    42 : SelectionDAGISel(TM) {}
    43
    44 virtual bool runOnFunction(Function &Fn) {
    45 // Make sure we re-emit a set of the global base reg if necessary
    46 GlobalBaseReg = 0;
    47 return SelectionDAGISel::runOnFunction(Fn);
    48 }
    49
    50 /// getI64Imm - Return a target constant with the specified value, of type
    51 /// i64.
    52 inline SDValue getI64Imm(uint64_t Imm) {
    53 return CurDAG->getTargetConstant(Imm, MVT::i64);
    54 }
    55
    56 /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC
    57 /// base register. Return the virtual register that holds this value.
    58 // SDValue getGlobalBaseReg(); TODO: hmm
    59
    60 // Select - Convert the specified operand from a target-independent to a
    61 // target-specific node if it hasn't already been changed.
    62 SDNode *Select(SDValue N);
    63
    64 SDNode *SelectIntImmediateExpr(SDValue LHS, SDValue RHS,
    65 unsigned OCHi, unsigned OCLo,
    66 bool IsArithmetic = false,
    67 bool Negate = false);
    68 SDNode *SelectBitfieldInsert(SDNode *N);
    69
    70 /// SelectCC - Select a comparison of the specified values with the
    71 /// specified condition code, returning the CR# of the expression.
    72 SDValue SelectCC(SDValue LHS, SDValue RHS, ISD::CondCode CC);
    73
    74 /// SelectAddr - Given the specified address, return the two operands for a
    75 /// load/store instruction, and return true if it should be an indexed [r+r]
    76 /// operation.
    77 bool SelectAddr(SDValue Addr, SDValue &Op1, SDValue &Op2);
    78
    79 /// InstructionSelect - This callback is invoked by
    80 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
    81 virtual void InstructionSelect();
    82
    83 virtual const char *getPassName() const {
    84 return "IA64 (Itanium) DAG->DAG Instruction Selector";
    85 }
    86
    87 // Include the pieces autogenerated from the target description.
    88 #include "IA64GenDAGISel.inc"
    89
    90 private:
    91 SDNode *SelectDIV(SDValue Op);
    92 };
    93 }
    94
    95 /// InstructionSelect - This callback is invoked by
    96 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
    97 void IA64DAGToDAGISel::InstructionSelect() {
    98 DEBUG(BB->dump());
    99
    100 // Select target instructions for the DAG.
    101 SelectRoot(*CurDAG);
    102 CurDAG->RemoveDeadNodes();
    103 }
    104
    105 SDNode *IA64DAGToDAGISel::SelectDIV(SDValue Op) {
    106 SDNode *N = Op.getNode();
    107 SDValue Chain = N->getOperand(0);
    108 SDValue Tmp1 = N->getOperand(0);
    109 SDValue Tmp2 = N->getOperand(1);
    110 DebugLoc dl = N->getDebugLoc();
    111
    112 bool isFP=false;
    113
    114 if(Tmp1.getValueType().isFloatingPoint())
    115 isFP=true;
    116
    117 bool isModulus=false; // is it a division or a modulus?
    118 bool isSigned=false;
    119
    120 switch(N->getOpcode()) {
    121 case ISD::FDIV:
    122 case ISD::SDIV: isModulus=false; isSigned=true; break;
    123 case ISD::UDIV: isModulus=false; isSigned=false; break;
    124 case ISD::FREM:
    125 case ISD::SREM: isModulus=true; isSigned=true; break;
    126 case ISD::UREM: isModulus=true; isSigned=false; break;
    127 }
    128
    129 // TODO: check for integer divides by powers of 2 (or other simple patterns?)
    130
    131 SDValue TmpPR, TmpPR2;
    132 SDValue TmpF1, TmpF2, TmpF3, TmpF4, TmpF5, TmpF6, TmpF7, TmpF8;
    133 SDValue TmpF9, TmpF10,TmpF11,TmpF12,TmpF13,TmpF14,TmpF15;
    134 SDNode *Result;
    135
    136 // we'll need copies of F0 and F1
    137 SDValue F0 = CurDAG->getRegister(IA64::F0, MVT::f64);
    138 SDValue F1 = CurDAG->getRegister(IA64::F1, MVT::f64);
    139
    140 // OK, emit some code:
    141
    142 if(!isFP) {
    143 // first, load the inputs into FP regs.
    144 TmpF1 =
    145 SDValue(CurDAG->getTargetNode(IA64::SETFSIG, dl, MVT::f64, Tmp1), 0);
    146 Chain = TmpF1.getValue(1);
    147 TmpF2 =
    148 SDValue(CurDAG->getTargetNode(IA64::SETFSIG, dl, MVT::f64, Tmp2), 0);
    149 Chain = TmpF2.getValue(1);
    150
    151 // next, convert the inputs to FP
    152 if(isSigned) {
    153 TmpF3 =
    154 SDValue(CurDAG->getTargetNode(IA64::FCVTXF, dl, MVT::f64, TmpF1), 0);
    155 Chain = TmpF3.getValue(1);
    156 TmpF4 =
    157 SDValue(CurDAG->getTargetNode(IA64::FCVTXF, dl, MVT::f64, TmpF2), 0);
    158 Chain = TmpF4.getValue(1);
    159 } else { // is unsigned
    160 TmpF3 =
    161 SDValue(CurDAG->getTargetNode(IA64::FCVTXUFS1, dl, MVT::f64, TmpF1),
    162 0);
    163 Chain = TmpF3.getValue(1);
    164 TmpF4 =
    165 SDValue(CurDAG->getTargetNode(IA64::FCVTXUFS1, dl, MVT::f64, TmpF2),
    166 0);
    167 Chain = TmpF4.getValue(1);
    168 }
    169
    170 } else { // this is an FP divide/remainder, so we 'leak' some temp
    171 // regs and assign TmpF3=Tmp1, TmpF4=Tmp2
    172 TmpF3=Tmp1;
    173 TmpF4=Tmp2;
    174 }
    175
    176 // we start by computing an approximate reciprocal (good to 9 bits?)
    177 // note, this instruction writes _both_ TmpF5 (answer) and TmpPR (predicate)
    178 if(isFP)
    179 TmpF5 = SDValue(CurDAG->getTargetNode(IA64::FRCPAS0, dl, MVT::f64,
    180 MVT::i1, TmpF3, TmpF4), 0);
    181 else
    182 TmpF5 = SDValue(CurDAG->getTargetNode(IA64::FRCPAS1, dl, MVT::f64,
    183 MVT::i1, TmpF3, TmpF4), 0);
    184
    185 TmpPR = TmpF5.getValue(1);
    186 Chain = TmpF5.getValue(2);
    187
    188 SDValue minusB;
    189 if(isModulus) { // for remainders, it'll be handy to have
    190 // copies of -input_b
    191 minusB = SDValue(CurDAG->getTargetNode(IA64::SUB, dl, MVT::i64,
    192 CurDAG->getRegister(IA64::r0, MVT::i64), Tmp2), 0);
    193 Chain = minusB.getValue(1);
    194 }
    195
    196 SDValue TmpE0, TmpY1, TmpE1, TmpY2;
    197
    198 SDValue OpsE0[] = { TmpF4, TmpF5, F1, TmpPR };
    199 TmpE0 = SDValue(CurDAG->getTargetNode(IA64::CFNMAS1, dl, MVT::f64,
    200 OpsE0, 4), 0);
    201 Chain = TmpE0.getValue(1);
    202 SDValue OpsY1[] = { TmpF5, TmpE0, TmpF5, TmpPR };
    203 TmpY1 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64,
    204 OpsY1, 4), 0);
    205 Chain = TmpY1.getValue(1);
    206 SDValue OpsE1[] = { TmpE0, TmpE0, F0, TmpPR };
    207 TmpE1 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64,
    208 OpsE1, 4), 0);
    209 Chain = TmpE1.getValue(1);
    210 SDValue OpsY2[] = { TmpY1, TmpE1, TmpY1, TmpPR };
    211 TmpY2 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64,
    212 OpsY2, 4), 0);
    213 Chain = TmpY2.getValue(1);
    214
    215 if(isFP) { // if this is an FP divide, we finish up here and exit early
    216 if(isModulus)
    217 llvm_unreachable("Sorry, try another FORTRAN compiler.");
    218
    219 SDValue TmpE2, TmpY3, TmpQ0, TmpR0;
    220
    221 SDValue OpsE2[] = { TmpE1, TmpE1, F0, TmpPR };
    222 TmpE2 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64,
    223 OpsE2, 4), 0);
    224 Chain = TmpE2.getValue(1);
    225 SDValue OpsY3[] = { TmpY2, TmpE2, TmpY2, TmpPR };
    226 TmpY3 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64,
    227 OpsY3, 4), 0);
    228 Chain = TmpY3.getValue(1);
    229 SDValue OpsQ0[] = { Tmp1, TmpY3, F0, TmpPR };
    230 TmpQ0 =
    231 SDValue(CurDAG->getTargetNode(IA64::CFMADS1, dl, // double prec!
    232 MVT::f64, OpsQ0, 4), 0);
    233 Chain = TmpQ0.getValue(1);
    234 SDValue OpsR0[] = { Tmp2, TmpQ0, Tmp1, TmpPR };
    235 TmpR0 =
    236 SDValue(CurDAG->getTargetNode(IA64::CFNMADS1, dl, // double prec!
    237 MVT::f64, OpsR0, 4), 0);
    238 Chain = TmpR0.getValue(1);
    239
    240 // we want Result to have the same target register as the frcpa, so
    241 // we two-address hack it. See the comment "for this to work..." on
    242 // page 48 of Intel application note #245415
    243 SDValue Ops[] = { TmpF5, TmpY3, TmpR0, TmpQ0, TmpPR };
    244 Result = CurDAG->getTargetNode(IA64::TCFMADS0, dl, // d.p. s0 rndg!
    245 MVT::f64, Ops, 5);
    246 Chain = SDValue(Result, 1);
    247 return Result; // XXX: early exit!
    248 } else { // this is *not* an FP divide, so there's a bit left to do:
    249
    250 SDValue TmpQ2, TmpR2, TmpQ3, TmpQ;
    251
    252 SDValue OpsQ2[] = { TmpF3, TmpY2, F0, TmpPR };
    253 TmpQ2 = SDValue(CurDAG->getTargetNode(IA64::CFMAS1, dl, MVT::f64,
    254 OpsQ2, 4), 0);
    255 Chain = TmpQ2.getValue(1);
    256 SDValue OpsR2[] = { TmpF4, TmpQ2, TmpF3, TmpPR };
    257 TmpR2 = SDValue(CurDAG->getTargetNode(IA64::CFNMAS1, dl, MVT::f64,
    258 OpsR2, 4), 0);
    259 Chain = TmpR2.getValue(1);
    260
    261 // we want TmpQ3 to have the same target register as the frcpa? maybe we
    262 // should two-address hack it. See the comment "for this to work..." on page
    263 // 48 of Intel application note #245415
    264 SDValue OpsQ3[] = { TmpF5, TmpR2, TmpY2, TmpQ2, TmpPR };
    265 TmpQ3 = SDValue(CurDAG->getTargetNode(IA64::TCFMAS1, dl, MVT::f64,
    266 OpsQ3, 5), 0);
    267 Chain = TmpQ3.getValue(1);
    268
    269 // STORY: without these two-address instructions (TCFMAS1 and TCFMADS0)
    270 // the FPSWA won't be able to help out in the case of large/tiny
    271 // arguments. Other fun bugs may also appear, e.g. 0/x = x, not 0.
    272
    273 if(isSigned)
    274 TmpQ = SDValue(CurDAG->getTargetNode(IA64::FCVTFXTRUNCS1, dl,
    275 MVT::f64, TmpQ3), 0);
    276 else
    277 TmpQ = SDValue(CurDAG->getTargetNode(IA64::FCVTFXUTRUNCS1, dl,
    278 MVT::f64, TmpQ3), 0);
    279
    280 Chain = TmpQ.getValue(1);
    281
    282 if(isModulus) {
    283 SDValue FPminusB =
    284 SDValue(CurDAG->getTargetNode(IA64::SETFSIG, dl, MVT::f64, minusB),
    285 0);
    286 Chain = FPminusB.getValue(1);
    287 SDValue Remainder =
    288 SDValue(CurDAG->getTargetNode(IA64::XMAL, dl, MVT::f64,
    289 TmpQ, FPminusB, TmpF1), 0);
    290 Chain = Remainder.getValue(1);
    291 Result = CurDAG->getTargetNode(IA64::GETFSIG, dl, MVT::i64, Remainder);
    292 Chain = SDValue(Result, 1);
    293 } else { // just an integer divide
    294 Result = CurDAG->getTargetNode(IA64::GETFSIG, dl, MVT::i64, TmpQ);
    295 Chain = SDValue(Result, 1);
    296 }
    297
    298 return Result;
    299 } // wasn't an FP divide
    300 }
    301
    302 // Select - Convert the specified operand from a target-independent to a
    303 // target-specific node if it hasn't already been changed.
    304 SDNode *IA64DAGToDAGISel::Select(SDValue Op) {
    305 SDNode *N = Op.getNode();
    306 if (N->isMachineOpcode())
    307 return NULL; // Already selected.
    308 DebugLoc dl = Op.getDebugLoc();
    309
    310 switch (N->getOpcode()) {
    311 default: break;
    312
    313 case IA64ISD::BRCALL: { // XXX: this is also a hack!
    314 SDValue Chain = N->getOperand(0);
    315 SDValue InFlag; // Null incoming flag value.
    316
    317 if(N->getNumOperands()==3) { // we have an incoming chain, callee and flag
    318 InFlag = N->getOperand(2);
    319 }
    320
    321 unsigned CallOpcode;
    322 SDValue CallOperand;
    323
    324 // if we can call directly, do so
    325 if (GlobalAddressSDNode *GASD =
    326 dyn_cast(N->getOperand(1))) {
    327 CallOpcode = IA64::BRCALL_IPREL_GA;
    328 CallOperand = CurDAG->getTargetGlobalAddress(GASD->getGlobal(), MVT::i64);
    329 } else if (isa(N->getOperand(1))) {
    330 // FIXME: we currently NEED this case for correctness, to avoid
    331 // "non-pic code with imm reloc.n against dynamic symbol" errors
    332 CallOpcode = IA64::BRCALL_IPREL_ES;
    333 CallOperand = N->getOperand(1);
    334 } else {
    335 // otherwise we need to load the function descriptor,
    336 // load the branch target (function)'s entry point and GP,
    337 // branch (call) then restore the GP
    338 SDValue FnDescriptor = N->getOperand(1);
    339
    340 // load the branch target's entry point [mem] and
    341 // GP value [mem+8]
    342 SDValue targetEntryPoint=
    343 SDValue(CurDAG->getTargetNode(IA64::LD8, dl, MVT::i64, MVT::Other,
    344 FnDescriptor, CurDAG->getEntryNode()), 0);
    345 Chain = targetEntryPoint.getValue(1);
    346 SDValue targetGPAddr=
    347 SDValue(CurDAG->getTargetNode(IA64::ADDS, dl, MVT::i64,
    348 FnDescriptor,
    349 CurDAG->getConstant(8, MVT::i64)), 0);
    350 Chain = targetGPAddr.getValue(1);
    351 SDValue targetGP =
    352 SDValue(CurDAG->getTargetNode(IA64::LD8, dl, MVT::i64,MVT::Other,
    353 targetGPAddr, CurDAG->getEntryNode()), 0);
    354 Chain = targetGP.getValue(1);
    355
    356 Chain = CurDAG->getCopyToReg(Chain, dl, IA64::r1, targetGP, InFlag);
    357 InFlag = Chain.getValue(1);
    358 Chain = CurDAG->getCopyToReg(Chain, dl, IA64::B6,
    359 targetEntryPoint, InFlag); // FLAG these?
    360 InFlag = Chain.getValue(1);
    361
    362 CallOperand = CurDAG->getRegister(IA64::B6, MVT::i64);
    363 CallOpcode = IA64::BRCALL_INDIRECT;
    364 }
    365
    366 // Finally, once everything is setup, emit the call itself
    367 if (InFlag.getNode())
    368 Chain = SDValue(CurDAG->getTargetNode(CallOpcode, dl, MVT::Other,
    369 MVT::Flag, CallOperand, InFlag), 0);
    370 else // there might be no arguments
    371 Chain = SDValue(CurDAG->getTargetNode(CallOpcode, dl, MVT::Other,
    372 MVT::Flag, CallOperand, Chain), 0);
    373 InFlag = Chain.getValue(1);
    374
    375 std::vector CallResults;
    376
    377 CallResults.push_back(Chain);
    378 CallResults.push_back(InFlag);
    379
    380 for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
    381 ReplaceUses(Op.getValue(i), CallResults[i]);
    382 return NULL;
    383 }
    384
    385 case IA64ISD::GETFD: {
    386 SDValue Input = N->getOperand(0);
    387 return CurDAG->getTargetNode(IA64::GETFD, dl, MVT::i64, Input);
    388 }
    389
    390 case ISD::FDIV:
    391 case ISD::SDIV:
    392 case ISD::UDIV:
    393 case ISD::SREM:
    394 case ISD::UREM:
    395 return SelectDIV(Op);
    396
    397 case ISD::TargetConstantFP: {
    398 SDValue Chain = CurDAG->getEntryNode(); // this is a constant, so..
    399
    400 SDValue V;
    401 ConstantFPSDNode* N2 = cast(N);
    402 if (N2->getValueAPF().isPosZero()) {
    403 V = CurDAG->getCopyFromReg(Chain, dl, IA64::F0, MVT::f64);
    404 } else if (N2->isExactlyValue(N2->getValueType(0) == MVT::f32 ?
    405 APFloat(+1.0f) : APFloat(+1.0))) {
    406 V = CurDAG->getCopyFromReg(Chain, dl, IA64::F1, MVT::f64);
    407 } else
    408 llvm_unreachable("Unexpected FP constant!");
    409
    410 ReplaceUses(SDValue(N, 0), V);
    411 return 0;
    412 }
    413
    414 case ISD::FrameIndex: { // TODO: reduce creepyness
    415 int FI = cast(N)->getIndex();
    416 if (N->hasOneUse())
    417 return CurDAG->SelectNodeTo(N, IA64::MOV, MVT::i64,
    418 CurDAG->getTargetFrameIndex(FI, MVT::i64));
    419 else
    420 return CurDAG->getTargetNode(IA64::MOV, dl, MVT::i64,
    421 CurDAG->getTargetFrameIndex(FI, MVT::i64));
    422 }
    423
    424 case ISD::ConstantPool: { // TODO: nuke the constant pool
    425 // (ia64 doesn't need one)
    426 ConstantPoolSDNode *CP = cast(N);
    427 Constant *C = CP->getConstVal();
    428 SDValue CPI = CurDAG->getTargetConstantPool(C, MVT::i64,
    429 CP->getAlignment());
    430 return CurDAG->getTargetNode(IA64::ADDL_GA, dl, MVT::i64, // ?
    431 CurDAG->getRegister(IA64::r1, MVT::i64), CPI);
    432 }
    433
    434 case ISD::GlobalAddress: {
    435 GlobalValue *GV = cast(N)->getGlobal();
    436 SDValue GA = CurDAG->getTargetGlobalAddress(GV, MVT::i64);
    437 SDValue Tmp =
    438 SDValue(CurDAG->getTargetNode(IA64::ADDL_GA, dl, MVT::i64,
    439 CurDAG->getRegister(IA64::r1,
    440 MVT::i64), GA), 0);
    441 return CurDAG->getTargetNode(IA64::LD8, dl, MVT::i64, MVT::Other, Tmp,
    442 CurDAG->getEntryNode());
    443 }
    444
    445 /* XXX
    446 case ISD::ExternalSymbol: {
    447 SDValue EA = CurDAG->getTargetExternalSymbol(
    448 cast(N)->getSymbol(),
    449 MVT::i64);
    450 SDValue Tmp = CurDAG->getTargetNode(IA64::ADDL_EA, dl, MVT::i64,
    451 CurDAG->getRegister(IA64::r1,
    452 MVT::i64),
    453 EA);
    454 return CurDAG->getTargetNode(IA64::LD8, dl, MVT::i64, Tmp);
    455 }
    456 */
    457
    458 case ISD::LOAD: { // FIXME: load -1, not 1, for bools?
    459 LoadSDNode *LD = cast(N);
    460 SDValue Chain = LD->getChain();
    461 SDValue Address = LD->getBasePtr();
    462
    463 MVT TypeBeingLoaded = LD->getMemoryVT();
    464 unsigned Opc;
    465 switch (TypeBeingLoaded.getSimpleVT()) {
    466 default:
    467 #ifndef NDEBUG
    468 N->dump(CurDAG);
    469 #endif
    470 llvm_unreachable("Cannot load this type!");
    471 case MVT::i1: { // this is a bool
    472 Opc = IA64::LD1; // first we load a byte, then compare for != 0
    473 if(N->getValueType(0) == MVT::i1) { // XXX: early exit!
    474 return CurDAG->SelectNodeTo(N, IA64::CMPNE, MVT::i1, MVT::Other,
    475 SDValue(CurDAG->getTargetNode(Opc, dl,
    476 MVT::i64,
    477 Address), 0),
    478 CurDAG->getRegister(IA64::r0, MVT::i64),
    479 Chain);
    480 }
    481 /* otherwise, we want to load a bool into something bigger: LD1
    482 will do that for us, so we just fall through */
    483 }
    484 case MVT::i8: Opc = IA64::LD1; break;
    485 case MVT::i16: Opc = IA64::LD2; break;
    486 case MVT::i32: Opc = IA64::LD4; break;
    487 case MVT::i64: Opc = IA64::LD8; break;
    488
    489 case MVT::f32: Opc = IA64::LDF4; break;
    490 case MVT::f64: Opc = IA64::LDF8; break;
    491 }
    492
    493 // TODO: comment this
    494 return CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other,
    495 Address, Chain);
    496 }
    497
    498 case ISD::STORE: {
    499 StoreSDNode *ST = cast(N);
    500 SDValue Address = ST->getBasePtr();
    501 SDValue Chain = ST->getChain();
    502
    503 unsigned Opc;
    504 if (ISD::isNON_TRUNCStore(N)) {
    505 switch (N->getOperand(1).getValueType().getSimpleVT()) {
    506 default: llvm_unreachable("unknown type in store");
    507 case MVT::i1: { // this is a bool
    508 Opc = IA64::ST1; // we store either 0 or 1 as a byte
    509 // first load zero!
    510 SDValue Initial = CurDAG->getCopyFromReg(Chain, dl, IA64::r0, MVT::i64);
    511 Chain = Initial.getValue(1);
    512 // then load 1 into the same reg iff the predicate to store is 1
    513 SDValue Tmp = ST->getValue();
    514 Tmp =
    515 SDValue(CurDAG->getTargetNode(IA64::TPCADDS, dl, MVT::i64, Initial,
    516 CurDAG->getTargetConstant(1,
    517 MVT::i64),
    518 Tmp), 0);
    519 return CurDAG->SelectNodeTo(N, Opc, MVT::Other, Address, Tmp, Chain);
    520 }
    521 case MVT::i64: Opc = IA64::ST8; break;
    522 case MVT::f64: Opc = IA64::STF8; break;
    523 }
    524 } else { // Truncating store
    525 switch(ST->getMemoryVT().getSimpleVT()) {
    526 default: llvm_unreachable("unknown type in truncstore");
    527 case MVT::i8: Opc = IA64::ST1; break;
    528 case MVT::i16: Opc = IA64::ST2; break;
    529 case MVT::i32: Opc = IA64::ST4; break;
    530 case MVT::f32: Opc = IA64::STF4; break;
    531 }
    532 }
    533
    534 SDValue N1 = N->getOperand(1);
    535 SDValue N2 = N->getOperand(2);
    536 return CurDAG->SelectNodeTo(N, Opc, MVT::Other, N2, N1, Chain);
    537 }
    538
    539 case ISD::BRCOND: {
    540 SDValue Chain = N->getOperand(0);
    541 SDValue CC = N->getOperand(1);
    542 MachineBasicBlock *Dest =
    543 cast(N->getOperand(2))->getBasicBlock();
    544 //FIXME - we do NOT need long branches all the time
    545 return CurDAG->SelectNodeTo(N, IA64::BRLCOND_NOTCALL, MVT::Other, CC,
    546 CurDAG->getBasicBlock(Dest), Chain);
    547 }
    548
    549 case ISD::CALLSEQ_START:
    550 case ISD::CALLSEQ_END: {
    551 int64_t Amt = cast(N->getOperand(1))->getZExtValue();
    552 unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ?
    553 IA64::ADJUSTCALLSTACKDOWN : IA64::ADJUSTCALLSTACKUP;
    554 SDValue N0 = N->getOperand(0);
    555 return CurDAG->SelectNodeTo(N, Opc, MVT::Other, getI64Imm(Amt), N0);
    556 }
    557
    558 case ISD::BR:
    559 // FIXME: we don't need long branches all the time!
    560 SDValue N0 = N->getOperand(0);
    561 return CurDAG->SelectNodeTo(N, IA64::BRL_NOTCALL, MVT::Other,
    562 N->getOperand(1), N0);
    563 }
    564
    565 return SelectCode(Op);
    566 }
    567
    568
    569 /// createIA64DAGToDAGInstructionSelector - This pass converts a legalized DAG
    570 /// into an IA64-specific DAG, ready for instruction scheduling.
    571 ///
    572 FunctionPass
    573 *llvm::createIA64DAGToDAGInstructionSelector(IA64TargetMachine &TM) {
    574 return new IA64DAGToDAGISel(TM);
    575 }
    576
    +0
    -633
    lib/Target/IA64/IA64ISelLowering.cpp less more
    None //===-- IA64ISelLowering.cpp - IA64 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 implements the IA64ISelLowering class.
    10 //
    11 //===----------------------------------------------------------------------===//
    12
    13 #include "IA64ISelLowering.h"
    14 #include "IA64MachineFunctionInfo.h"
    15 #include "IA64TargetMachine.h"
    16 #include "llvm/CodeGen/MachineFrameInfo.h"
    17 #include "llvm/CodeGen/MachineFunction.h"
    18 #include "llvm/CodeGen/MachineInstrBuilder.h"
    19 #include "llvm/CodeGen/SelectionDAG.h"
    20 #include "llvm/CodeGen/MachineRegisterInfo.h"
    21 #include "llvm/Support/ErrorHandling.h"
    22 #include "llvm/Support/raw_ostream.h"
    23 #include "llvm/Constants.h"
    24 #include "llvm/Function.h"
    25 using namespace llvm;
    26
    27 IA64TargetLowering::IA64TargetLowering(TargetMachine &TM)
    28 : TargetLowering(TM) {
    29
    30 // register class for general registers
    31 addRegisterClass(MVT::i64, IA64::GRRegisterClass);
    32
    33 // register class for FP registers
    34 addRegisterClass(MVT::f64, IA64::FPRegisterClass);
    35
    36 // register class for predicate registers
    37 addRegisterClass(MVT::i1, IA64::PRRegisterClass);
    38
    39 setLoadExtAction(ISD::EXTLOAD , MVT::i1 , Promote);
    40
    41 setLoadExtAction(ISD::ZEXTLOAD , MVT::i1 , Promote);
    42
    43 setLoadExtAction(ISD::SEXTLOAD , MVT::i1 , Promote);
    44 setLoadExtAction(ISD::SEXTLOAD , MVT::i8 , Expand);
    45 setLoadExtAction(ISD::SEXTLOAD , MVT::i16 , Expand);
    46 setLoadExtAction(ISD::SEXTLOAD , MVT::i32 , Expand);
    47
    48 setOperationAction(ISD::BRIND , MVT::Other, Expand);
    49 setOperationAction(ISD::BR_JT , MVT::Other, Expand);
    50 setOperationAction(ISD::BR_CC , MVT::Other, Expand);
    51 setOperationAction(ISD::FP_ROUND_INREG , MVT::f32 , Expand);
    52
    53 // ia64 uses SELECT not SELECT_CC
    54 setOperationAction(ISD::SELECT_CC , MVT::Other, Expand);
    55
    56 // We need to handle ISD::RET for void functions ourselves,
    57 // so we get a chance to restore ar.pfs before adding a
    58 // br.ret insn
    59 setOperationAction(ISD::RET, MVT::Other, Custom);
    60
    61 setShiftAmountType(MVT::i64);
    62
    63 setOperationAction(ISD::FREM , MVT::f32 , Expand);
    64 setOperationAction(ISD::FREM , MVT::f64 , Expand);
    65
    66 setOperationAction(ISD::UREM , MVT::f32 , Expand);
    67 setOperationAction(ISD::UREM , MVT::f64 , Expand);
    68
    69 setOperationAction(ISD::MEMBARRIER , MVT::Other, Expand);
    70
    71 setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
    72 setOperationAction(ISD::UINT_TO_FP , MVT::i1 , Promote);
    73
    74 // We don't support sin/cos/sqrt/pow
    75 setOperationAction(ISD::FSIN , MVT::f64, Expand);
    76 setOperationAction(ISD::FCOS , MVT::f64, Expand);
    77 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
    78 setOperationAction(ISD::FPOW , MVT::f64, Expand);
    79 setOperationAction(ISD::FSIN , MVT::f32, Expand);
    80 setOperationAction(ISD::FCOS , MVT::f32, Expand);
    81 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
    82 setOperationAction(ISD::FPOW , MVT::f32, Expand);
    83
    84 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand);
    85
    86 // FIXME: IA64 supports fcopysign natively!
    87 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
    88 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
    89
    90 // We don't have line number support yet.
    91 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
    92 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
    93 setOperationAction(ISD::DBG_LABEL, MVT::Other, Expand);
    94 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
    95
    96 // IA64 has ctlz in the form of the 'fnorm' instruction. The Legalizer
    97 // expansion for ctlz/cttz in terms of ctpop is much larger, but lower
    98 // latency.
    99 // FIXME: Custom lower CTLZ when compiling for size?
    100 setOperationAction(ISD::CTLZ , MVT::i64 , Expand);
    101 setOperationAction(ISD::CTTZ , MVT::i64 , Expand);
    102 setOperationAction(ISD::ROTL , MVT::i64 , Expand);
    103 setOperationAction(ISD::ROTR , MVT::i64 , Expand);
    104
    105 // FIXME: IA64 has this, but is not implemented. should be mux @rev
    106 setOperationAction(ISD::BSWAP, MVT::i64 , Expand);
    107
    108 // VASTART needs to be custom lowered to use the VarArgsFrameIndex
    109 setOperationAction(ISD::VAARG , MVT::Other, Custom);
    110 setOperationAction(ISD::VASTART , MVT::Other, Custom);
    111
    112 // FIXME: These should be legal
    113 setOperationAction(ISD::BIT_CONVERT, MVT::i64, Expand);
    114 setOperationAction(ISD::BIT_CONVERT, MVT::f64, Expand);
    115
    116 // Use the default implementation.
    117 setOperationAction(ISD::VACOPY , MVT::Other, Expand);
    118 setOperationAction(ISD::VAEND , MVT::Other, Expand);
    119 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
    120 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
    121 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand);
    122
    123 // Thread Local Storage
    124 setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
    125
    126 setStackPointerRegisterToSaveRestore(IA64::r12);
    127
    128 setJumpBufSize(704); // on ia64-linux, jmp_bufs are 704 bytes..
    129 setJumpBufAlignment(16); // ...and must be 16-byte aligned
    130
    131 computeRegisterProperties();
    132
    133 addLegalFPImmediate(APFloat(+0.0));
    134 addLegalFPImmediate(APFloat(-0.0));
    135 addLegalFPImmediate(APFloat(+1.0));
    136 addLegalFPImmediate(APFloat(-1.0));
    137 }
    138
    139 const char *IA64TargetLowering::getTargetNodeName(unsigned Opcode) const {
    140 switch (Opcode) {
    141 default: return 0;
    142 case IA64ISD::GETFD: return "IA64ISD::GETFD";
    143 case IA64ISD::BRCALL: return "IA64ISD::BRCALL";
    144 case IA64ISD::RET_FLAG: return "IA64ISD::RET_FLAG";
    145 }
    146 }
    147
    148 MVT IA64TargetLowering::getSetCCResultType(MVT VT) const {
    149 return MVT::i1;
    150 }
    151
    152 /// getFunctionAlignment - Return the Log2 alignment of this function.
    153 unsigned IA64TargetLowering::getFunctionAlignment(const Function *) const {
    154 return 5;
    155 }
    156
    157 void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
    158 SmallVectorImpl &ArgValues,
    159 DebugLoc dl) {
    160 //
    161 // add beautiful description of IA64 stack frame format
    162 // here (from intel 24535803.pdf most likely)
    163 //
    164 MachineFunction &MF = DAG.getMachineFunction();
    165 MachineFrameInfo *MFI = MF.getFrameInfo();
    166 const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
    167
    168 GP = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));
    169 SP = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));
    170 RP = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));
    171
    172 MachineBasicBlock& BB = MF.front();
    173
    174 unsigned args_int[] = {IA64::r32, IA64::r33, IA64::r34, IA64::r35,
    175 IA64::r36, IA64::r37, IA64::r38, IA64::r39};
    176
    177 unsigned args_FP[] = {IA64::F8, IA64::F9, IA64::F10, IA64::F11,
    178 IA64::F12,IA64::F13,IA64::F14, IA64::F15};
    179
    180 unsigned argVreg[8];
    181 unsigned argPreg[8];
    182 unsigned argOpc[8];
    183
    184 unsigned used_FPArgs = 0; // how many FP args have been used so far?
    185
    186 unsigned ArgOffset = 0;
    187 int count = 0;
    188
    189 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
    190 {
    191 SDValue newroot, argt;
    192 if(count < 8) { // need to fix this logic? maybe.
    193
    194 switch (getValueType(I->getType()).getSimpleVT()) {
    195 default:
    196 llvm_unreachable("ERROR in LowerArgs: can't lower this type of arg.");
    197 case MVT::f32:
    198 // fixme? (well, will need to for weird FP structy stuff,
    199 // see intel ABI docs)
    200 case MVT::f64:
    201 //XXX BuildMI(&BB, IA64::IDEF, 0, args_FP[used_FPArgs]);
    202 MF.getRegInfo().addLiveIn(args_FP[used_FPArgs]);
    203 // mark this reg as liveIn
    204 // floating point args go into f8..f15 as-needed, the increment
    205 argVreg[count] = // is below..:
    206 MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::f64));
    207 // FP args go into f8..f15 as needed: (hence the ++)
    208 argPreg[count] = args_FP[used_FPArgs++];
    209 argOpc[count] = IA64::FMOV;
    210 argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), dl,
    211 argVreg[count], MVT::f64);
    212 if (I->getType() == Type::FloatTy)
    213 argt = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, argt,
    214 DAG.getIntPtrConstant(0));
    215 break;
    216 case MVT::i1: // NOTE: as far as C abi stuff goes,
    217 // bools are just boring old ints
    218 case MVT::i8:
    219 case MVT::i16:
    220 case MVT::i32:
    221 case MVT::i64:
    222 //XXX BuildMI(&BB, IA64::IDEF, 0, args_int[count]);
    223 MF.getRegInfo().addLiveIn(args_int[count]);
    224 // mark this register as liveIn
    225 argVreg[count] =
    226 MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));
    227 argPreg[count] = args_int[count];
    228 argOpc[count] = IA64::MOV;
    229 argt = newroot =
    230 DAG.getCopyFromReg(DAG.getRoot(), dl, argVreg[count], MVT::i64);
    231 if ( getValueType(I->getType()) != MVT::i64)
    232 argt = DAG.getNode(ISD::TRUNCATE, dl, getValueType(I->getType()),
    233 newroot);
    234 break;
    235 }
    236 } else { // more than 8 args go into the frame
    237 // Create the frame index object for this incoming parameter...
    238 ArgOffset = 16 + 8 * (count - 8);
    239 int FI = MFI->CreateFixedObject(8, ArgOffset);
    240
    241 // Create the SelectionDAG nodes corresponding to a load
    242 //from this parameter
    243 SDValue FIN = DAG.getFrameIndex(FI, MVT::i64);
    244 argt = newroot = DAG.getLoad(getValueType(I->getType()), dl,
    245 DAG.getEntryNode(), FIN, NULL, 0);
    246 }
    247 ++count;
    248 DAG.setRoot(newroot.getValue(1));
    249 ArgValues.push_back(argt);
    250 }
    251
    252
    253 // Create a vreg to hold the output of (what will become)
    254 // the "alloc" instruction
    255 VirtGPR = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));
    256 BuildMI(&BB, dl, TII->get(IA64::PSEUDO_ALLOC), VirtGPR);
    257 // we create a PSEUDO_ALLOC (pseudo)instruction for now
    258 /*
    259 BuildMI(&BB, IA64::IDEF, 0, IA64::r1);
    260
    261 // hmm:
    262 BuildMI(&BB, IA64::IDEF, 0, IA64::r12);
    263 BuildMI(&BB, IA64::IDEF, 0, IA64::rp);
    264 // ..hmm.
    265
    266 BuildMI(&BB, IA64::MOV, 1, GP).addReg(IA64::r1);
    267
    268 // hmm:
    269 BuildMI(&BB, IA64::MOV, 1, SP).addReg(IA64::r12);
    270 BuildMI(&BB, IA64::MOV, 1, RP).addReg(IA64::rp);
    271 // ..hmm.
    272 */
    273
    274 unsigned tempOffset=0;
    275
    276 // if this is a varargs function, we simply lower llvm.va_start by
    277 // pointing to the first entry
    278 if(F.isVarArg()) {
    279 tempOffset=0;
    280 VarArgsFrameIndex = MFI->CreateFixedObject(8, tempOffset);
    281 }
    282
    283 // here we actually do the moving of args, and store them to the stack
    284 // too if this is a varargs function:
    285 for (int i = 0; i < count && i < 8; ++i) {
    286 BuildMI(&BB, dl, TII->get(argOpc[i]), argVreg[i]).addReg(argPreg[i]);
    287 if(F.isVarArg()) {
    288 // if this is a varargs function, we copy the input registers to the stack
    289 int FI = MFI->CreateFixedObject(8, tempOffset);
    290 tempOffset+=8; //XXX: is it safe to use r22 like this?
    291 BuildMI(&BB, dl, TII->get(IA64::MOV), IA64::r22).addFrameIndex(FI);
    292 // FIXME: we should use st8.spill here, one day
    293 BuildMI(&BB, dl, TII->get(IA64::ST8), IA64::r22).addReg(argPreg[i]);
    294 }
    295 }
    296
    297 // Finally, inform the code generator which regs we return values in.
    298 // (see the ISD::RET: case in the instruction selector)
    299 switch (getValueType(F.getReturnType()).getSimpleVT()) {
    300 default: llvm_unreachable("i have no idea where to return this type!");
    301 case MVT::isVoid: break;
    302 case MVT::i1:
    303 case MVT::i8:
    304 case MVT::i16:
    305 case MVT::i32:
    306 case MVT::i64:
    307 MF.getRegInfo().addLiveOut(IA64::r8);
    308 break;
    309 case MVT::f32:
    310 case MVT::f64:
    311 MF.getRegInfo().addLiveOut(IA64::F8);
    312 break;
    313 }
    314 }
    315
    316 std::pair
    317 IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
    318 bool RetSExt, bool RetZExt, bool isVarArg,
    319 bool isInreg, unsigned NumFixedArgs,
    320 unsigned CallingConv,
    321 bool isTailCall, SDValue Callee,
    322 ArgListTy &Args, SelectionDAG &DAG,
    323 DebugLoc dl) {
    324
    325 MachineFunction &MF = DAG.getMachineFunction();
    326
    327 unsigned NumBytes = 16;
    328 unsigned outRegsUsed = 0;
    329
    330 if (Args.size() > 8) {
    331 NumBytes += (Args.size() - 8) * 8;
    332 outRegsUsed = 8;
    333 } else {
    334 outRegsUsed = Args.size();
    335 }
    336
    337 // FIXME? this WILL fail if we ever try to pass around an arg that
    338 // consumes more than a single output slot (a 'real' double, int128
    339 // some sort of aggregate etc.), as we'll underestimate how many 'outX'
    340 // registers we use. Hopefully, the assembler will notice.
    341 MF.getInfo()->outRegsUsed=
    342 std::max(outRegsUsed, MF.getInfo()->outRegsUsed);
    343
    344 // keep stack frame 16-byte aligned
    345 // assert(NumBytes==((NumBytes+15) & ~15) &&
    346 // "stack frame not 16-byte aligned!");
    347 NumBytes = (NumBytes+15) & ~15;
    348
    349 Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true));
    350
    351 SDValue StackPtr;
    352 std::vector Stores;
    353 std::vector Converts;
    354 std::vector RegValuesToPass;
    355 unsigned ArgOffset = 16;
    356
    357 for (unsigned i = 0, e = Args.size(); i != e; ++i)
    358 {
    359 SDValue Val = Args[i].Node;
    360 MVT ObjectVT = Val.getValueType();
    361 SDValue ValToStore(0, 0), ValToConvert(0, 0);
    362 unsigned ObjSize=8;
    363 switch (ObjectVT.getSimpleVT()) {
    364 default: llvm_unreachable("unexpected argument type!");
    365 case MVT::i1:
    366 case MVT::i8:
    367 case MVT::i16:
    368 case MVT::i32: {
    369 //promote to 64-bits, sign/zero extending based on type
    370 //of the argument
    371 ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
    372 if (Args[i].isSExt)
    373 ExtendKind = ISD::SIGN_EXTEND;
    374 else if (Args[i].isZExt)
    375 ExtendKind = ISD::ZERO_EXTEND;
    376 Val = DAG.getNode(ExtendKind, dl, MVT::i64, Val);
    377 // XXX: fall through
    378 }
    379 case MVT::i64:
    380 //ObjSize = 8;
    381 if(RegValuesToPass.size() >= 8) {
    382 ValToStore = Val;
    383 } else {
    384 RegValuesToPass.push_back(Val);
    385 }
    386 break;
    387 case MVT::f32:
    388 //promote to 64-bits
    389 Val = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Val);
    390 // XXX: fall through
    391 case MVT::f64:
    392 if(RegValuesToPass.size() >= 8) {
    393 ValToStore = Val;
    394 } else {
    395 RegValuesToPass.push_back(Val);
    396 if(1 /* TODO: if(calling external or varadic function)*/ ) {
    397 ValToConvert = Val; // additionally pass this FP value as an int
    398 }
    399 }
    400 break;
    401 }
    402
    403 if(ValToStore.getNode()) {
    404 if(!StackPtr.getNode()) {
    405 StackPtr = DAG.getRegister(IA64::r12, MVT::i64);
    406 }
    407 SDValue PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
    408 PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i64, StackPtr, PtrOff);
    409 Stores.push_back(DAG.getStore(Chain, dl, ValToStore, PtrOff, NULL, 0));
    410 ArgOffset += ObjSize;
    411 }
    412
    413 if(ValToConvert.getNode()) {
    414 Converts.push_back(DAG.getNode(IA64ISD::GETFD, dl,
    415 MVT::i64, ValToConvert));
    416 }
    417 }
    418
    419 // Emit all stores, make sure they occur before any copies into physregs.
    420 if (!Stores.empty())
    421 Chain = DAG.getNode(ISD::TokenFactor, dl,
    422 MVT::Other, &Stores[0],Stores.size());
    423
    424 static const unsigned IntArgRegs[] = {
    425 IA64::out0, IA64::out1, IA64::out2, IA64::out3,
    426 IA64::out4, IA64::out5, IA64::out6, IA64::out7
    427 };
    428
    429 static const unsigned FPArgRegs[] = {
    430 IA64::F8, IA64::F9, IA64::F10, IA64::F11,
    431 IA64::F12, IA64::F13, IA64::F14, IA64::F15
    432 };
    433
    434 SDValue InFlag;
    435
    436 // save the current GP, SP and RP : FIXME: do we need to do all 3 always?
    437 SDValue GPBeforeCall = DAG.getCopyFromReg(Chain, dl, IA64::r1,
    438 MVT::i64, InFlag);
    439 Chain = GPBeforeCall.getValue(1);
    440 InFlag = Chain.getValue(2);
    441 SDValue SPBeforeCall = DAG.getCopyFromReg(Chain, dl, IA64::r12,
    442 MVT::i64, InFlag);
    443 Chain = SPBeforeCall.getValue(1);
    444 InFlag = Chain.getValue(2);
    445 SDValue RPBeforeCall = DAG.getCopyFromReg(Chain, dl, IA64::rp,
    446 MVT::i64, InFlag);
    447 Chain = RPBeforeCall.getValue(1);
    448 InFlag = Chain.getValue(2);
    449
    450 // Build a sequence of copy-to-reg nodes chained together with token chain
    451 // and flag operands which copy the outgoing integer args into regs out[0-7]
    452 // mapped 1:1 and the FP args into regs F8-F15 "lazily"
    453 // TODO: for performance, we should only copy FP args into int regs when we
    454 // know this is required (i.e. for varardic or external (unknown) functions)
    455
    456 // first to the FP->(integer representation) conversions, these are
    457 // flagged for now, but shouldn't have to be (TODO)
    458 unsigned seenConverts = 0;
    459 for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) {
    460 if(RegValuesToPass[i].getValueType().isFloatingPoint()) {
    461 Chain = DAG.getCopyToReg(Chain, dl, IntArgRegs[i],
    462 Converts[seenConverts++], InFlag);
    463 InFlag = Chain.getValue(1);
    464 }
    465 }
    466
    467 // next copy args into the usual places, these are flagged
    468 unsigned usedFPArgs = 0;
    469 for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) {
    470 Chain = DAG.getCopyToReg(Chain, dl,
    471 RegValuesToPass[i].getValueType().isInteger() ?
    472 IntArgRegs[i] : FPArgRegs[usedFPArgs++], RegValuesToPass[i], InFlag);
    473 InFlag = Chain.getValue(1);
    474 }
    475
    476 // If the callee is a GlobalAddress node (quite common, every direct call is)
    477 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
    478 /*
    479 if (GlobalAddressSDNode *G = dyn_cast(Callee)) {
    480 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i64);
    481 }
    482 */
    483
    484 std::vector NodeTys;
    485 std::vector CallOperands;
    486 NodeTys.push_back(MVT::Other); // Returns a chain
    487 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use.
    488 CallOperands.push_back(Chain);
    489 CallOperands.push_back(Callee);
    490
    491 // emit the call itself
    492 if (InFlag.getNode())
    493 CallOperands.push_back(InFlag);
    494 else
    495 llvm_unreachable("this should never happen!");
    496
    497 // to make way for a hack:
    498 Chain = DAG.getNode(IA64ISD::BRCALL, dl, NodeTys,
    499 &CallOperands[0], CallOperands.size());
    500 InFlag = Chain.getValue(1);
    501
    502 // restore the GP, SP and RP after the call
    503 Chain = DAG.getCopyToReg(Chain, dl, IA64::r1, GPBeforeCall, InFlag);
    504 InFlag = Chain.getValue(1);
    505 Chain = DAG.getCopyToReg(Chain, dl, IA64::r12, SPBeforeCall, InFlag);
    506 InFlag = Chain.getValue(1);
    507 Chain = DAG.getCopyToReg(Chain, dl, IA64::rp, RPBeforeCall, InFlag);
    508 InFlag = Chain.getValue(1);
    509
    510 std::vector RetVals;
    511 RetVals.push_back(MVT::Other);
    512 RetVals.push_back(MVT::Flag);
    513
    514 MVT RetTyVT = getValueType(RetTy);
    515 SDValue RetVal;
    516 if (RetTyVT != MVT::isVoid) {
    517 switch (RetTyVT.getSimpleVT()) {
    518 default: llvm_unreachable("Unknown value type to return!");
    519 case MVT::i1: { // bools are just like other integers (returned in r8)
    520 // we *could* fall through to the truncate below, but this saves a
    521 // few redundant predicate ops
    522 SDValue boolInR8 = DAG.getCopyFromReg(Chain, dl, IA64::r8,
    523 MVT::i64,InFlag);
    524 InFlag = boolInR8.getValue(2);
    525 Chain = boolInR8.getValue(1);
    526 SDValue zeroReg = DAG.getCopyFromReg(Chain, dl, IA64::r0,
    527 MVT::i64, InFlag);
    528 InFlag = zeroReg.getValue(2);
    529 Chain = zeroReg.getValue(1);
    530
    531 RetVal = DAG.getSetCC(dl, MVT::i1, boolInR8, zeroReg, ISD::SETNE);
    532 break;
    533 }
    534 case MVT::i8:
    535 case MVT::i16:
    536 case MVT::i32:
    537 RetVal = DAG.getCopyFromReg(Chain, dl, IA64::r8, MVT::i64, InFlag);
    538 Chain = RetVal.getValue(1);
    539
    540 // keep track of whether it is sign or zero extended (todo: bools?)
    541 /* XXX
    542 RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext :ISD::AssertZext,
    543 dl, MVT::i64, RetVal, DAG.getValueType(RetTyVT));
    544 */
    545 RetVal = DAG.getNode(ISD::TRUNCATE, dl, RetTyVT, RetVal);
    546 break;
    547 case MVT::i64:
    548 RetVal = DAG.getCopyFromReg(Chain, dl, IA64::r8, MVT::i64, InFlag);
    549 Chain = RetVal.getValue(1);
    550 InFlag = RetVal.getValue(2); // XXX dead
    551 break;
    552 case MVT::f32:
    553 RetVal = DAG.getCopyFromReg(Chain, dl, IA64::F8, MVT::f64, InFlag);
    554 Chain = RetVal.getValue(1);
    555 RetVal = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, RetVal,
    556 DAG.getIntPtrConstant(0));
    557 break;
    558 case MVT::f64:
    559 RetVal = DAG.getCopyFromReg(Chain, dl, IA64::F8, MVT::f64, InFlag);
    560 Chain = RetVal.getValue(1);
    561 InFlag = RetVal.getValue(2); // XXX dead
    562 break;
    563 }
    564 }
    565
    566 Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true),
    567 DAG.getIntPtrConstant(0, true), SDValue());
    568 return std::make_pair(RetVal, Chain);
    569 }
    570
    571 SDValue IA64TargetLowering::
    572 LowerOperation(SDValue Op, SelectionDAG &DAG) {
    573 DebugLoc dl = Op.getDebugLoc();
    574 switch (Op.getOpcode()) {
    575 default: llvm_unreachable("Should not custom lower this!");
    576 case ISD::GlobalTLSAddress:
    577 llvm_unreachable("TLS not implemented for IA64.");
    578 case ISD::RET: {
    579 SDValue AR_PFSVal, Copy;
    580
    581 switch(Op.getNumOperands()) {
    582 default:
    583 llvm_unreachable("Do not know how to return this many arguments!");
    584 case 1:
    585 AR_PFSVal = DAG.getCopyFromReg(Op.getOperand(0), dl, VirtGPR, MVT::i64);
    586 AR_PFSVal = DAG.getCopyToReg(AR_PFSVal.getValue(1), dl, IA64::AR_PFS,
    587 AR_PFSVal);
    588 return DAG.getNode(IA64ISD::RET_FLAG, dl, MVT::Other, AR_PFSVal);
    589 case 3: {
    590 // Copy the result into the output register & restore ar.pfs
    591 MVT ArgVT = Op.getOperand(1).getValueType();
    592 unsigned ArgReg = ArgVT.isInteger() ? IA64::r8 : IA64::F8;
    593
    594 AR_PFSVal = DAG.getCopyFromReg(Op.getOperand(0), dl, VirtGPR, MVT::i64);
    595 Copy = DAG.getCopyToReg(AR_PFSVal.getValue(1), dl, ArgReg,
    596 Op.getOperand(1), SDValue());
    597 AR_PFSVal = DAG.getCopyToReg(Copy.getValue(0), dl,
    598 IA64::AR_PFS, AR_PFSVal, Copy.getValue(1));
    599 return DAG.getNode(IA64ISD::RET_FLAG, dl, MVT::Other,
    600 AR_PFSVal, AR_PFSVal.getValue(1));
    601 }
    602 }
    603 return SDValue();
    604 }
    605 case ISD::VAARG: {
    606 MVT VT = getPointerTy();
    607 const Value *SV = cast(Op.getOperand(2))->getValue();
    608 SDValue VAList = DAG.getLoad(VT, dl, Op.getOperand(0), Op.getOperand(1),
    609 SV, 0);
    610 // Increment the pointer, VAList, to the next vaarg
    611 SDValue VAIncr = DAG.getNode(ISD::ADD, dl, VT, VAList,
    612 DAG.getConstant(VT.getSizeInBits()/8,
    613 VT));
    614 // Store the incremented VAList to the legalized pointer
    615 VAIncr = DAG.getStore(VAList.getValue(1), dl, VAIncr,
    616 Op.getOperand(1), SV, 0);
    617 // Load the actual argument out of the pointer VAList
    618 return DAG.getLoad(Op.getValueType(), dl, VAIncr, VAList, NULL, 0);
    619 }
    620 case ISD::VASTART: {
    621 // vastart just stores the address of the VarArgsFrameIndex slot into the
    622 // memory location argument.
    623 SDValue FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i64);
    624 const Value *SV = cast(Op.getOperand(2))->getValue();
    625 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1), SV, 0);
    626 }
    627 // Frame & Return address. Currently unimplemented
    628 case ISD::RETURNADDR: break;
    629 case ISD::FRAMEADDR: break;
    630 }
    631 return SDValue();
    632 }
    +0
    -78
    lib/Target/IA64/IA64ISelLowering.h less more
    None //===-- IA64ISelLowering.h - IA64 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 IA64 uses to lower LLVM code into a
    10 // selection DAG.
    11 //
    12 //===----------------------------------------------------------------------===//
    13
    14 #ifndef LLVM_TARGET_IA64_IA64ISELLOWERING_H
    15 #define LLVM_TARGET_IA64_IA64ISELLOWERING_H
    16
    17 #include "llvm/Target/TargetLowering.h"
    18 #include "llvm/CodeGen/SelectionDAG.h"
    19 #include "IA64.h"
    20
    21 namespace llvm {
    22 namespace IA64ISD {
    23 enum NodeType {
    24 // Start the numbering where the builting ops and target ops leave off.
    25 FIRST_NUMBER = ISD::BUILTIN_OP_END,
    26
    27 /// GETFD - the getf.d instruction takes a floating point operand and
    28 /// returns its 64-bit memory representation as an i64
    29 GETFD,
    30
    31 // TODO: explain this hack
    32 BRCALL,
    33
    34 // RET_FLAG - Return with a flag operand
    35 RET_FLAG
    36 };
    37 }
    38
    39 class IA64TargetLowering : public TargetLowering {
    40 int VarArgsFrameIndex; // FrameIndex for start of varargs area.
    41 //int ReturnAddrIndex; // FrameIndex for return slot.
    42 unsigned GP, SP, RP; // FIXME - clean this mess up
    43 public:
    44 explicit IA64TargetLowering(TargetMachine &TM);
    45
    46 unsigned VirtGPR; // this is public so it can be accessed in the selector
    47 // for ISD::RET. add an accessor instead? FIXME
    48 const char *getTargetNodeName(unsigned Opcode) const;
    49
    50 /// getSetCCResultType: return ISD::SETCC's result type.
    51 virtual MVT getSetCCResultType(MVT VT) const;
    52
    53 /// LowerArguments - This hook must be implemented to indicate how we should
    54 /// lower the arguments for the specified function, into the specified DAG.
    55 virtual void LowerArguments(Function &F, SelectionDAG &DAG,
    56 SmallVectorImpl &ArgValues,
    57 DebugLoc dl);
    58
    59 /// LowerCallTo - This hook lowers an abstract call to a function into an
    60 /// actual call.
    61 virtual std::pair
    62 LowerCallTo(SDValue Chain, const Type *RetTy,
    63 bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg,
    64 unsigned NumFixedArgs, unsigned CC, bool isTailCall,
    65 SDValue Callee, ArgListTy &Args, SelectionDAG &DAG,
    66 DebugLoc dl);
    67
    68 /// LowerOperation - for custom lowering specific ops
    69 /// (currently, only "ret void")
    70 virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG);
    71
    72 /// getFunctionAlignment - Return the Log2 alignment of this function.
    73 virtual unsigned getFunctionAlignment(const Function *F) const;
    74 };
    75 }
    76
    77 #endif // LLVM_TARGET_IA64_IA64ISELLOWERING_H
    +0
    -40
    lib/Target/IA64/IA64InstrBuilder.h less more
    None //===-- IA64PCInstrBuilder.h - Aids for building IA64 insts -----*- 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 exposes functions that may be used with BuildMI from the
    10 // MachineInstrBuilder.h file to simplify generating frame and constant pool
    11 // references.
    12 //
    13 //===----------------------------------------------------------------------===//
    14
    15 #ifndef IA64_INSTRBUILDER_H
    16 #define IA64_INSTRBUILDER_H
    17
    18 #include "llvm/CodeGen/MachineInstrBuilder.h"
    19
    20 namespace llvm {
    21
    22 /// addFrameReference - This function is used to add a reference to the base of
    23 /// an abstract object on the stack frame of the current function. This
    24 /// reference has base register as the FrameIndex offset until it is resolved.
    25 /// This allows a constant offset to be specified as well...
    26 ///
    27 inline const MachineInstrBuilder&
    28 addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset = 0,
    29 bool mem = true) {
    30 if (mem)
    31 return MIB.addImm(Offset).addFrameIndex(FI);
    32 else
    33 return MIB.addFrameIndex(FI).addImm(Offset);
    34 }
    35
    36 } // End llvm namespace
    37
    38 #endif
    39
    +0
    -80
    lib/Target/IA64/IA64InstrFormats.td less more
    None //===- IA64InstrFormats.td - IA64 Instruction Formats --*- tablegen -*-=//
    1 //
    2 // The LLVM Compiler Infrastructure
    3 //
    4 // This file is distributed under the University of Illinois Open Source
    5 // License. See LICENSE.TXT for details.
    6 //
    7 //===----------------------------------------------------------------------===//
    8 //
    9 // - Warning: the stuff in here isn't really being used, so is mostly
    10 // junk. It'll get fixed as the JIT gets built.
    11 //
    12 //===----------------------------------------------------------------------===//
    13
    14 //===----------------------------------------------------------------------===//
    15 // Instruction format superclass
    16 //===----------------------------------------------------------------------===//
    17
    18 class InstIA64 op, dag OOL, dag IOL, string asmstr> : Instruction {
    19 // IA64 instruction baseline
    20 field bits<41> Inst;
    21 let Namespace = "IA64";
    22 let OutOperandList = OOL;
    23 let InOperandList = IOL;
    24 let AsmString = asmstr;
    25
    26 let Inst{40-37} = op;
    27 }
    28
    29 //"Each Itanium instruction is categorized into one of six types."
    30 //We should have:
    31 // A, I, M, F, B, L+X
    32
    33 class AForm opcode, bits<6> qpReg, dag OOL, dag IOL, string asmstr> :
    34 InstIA64 {
    35
    36 let Inst{5-0} = qpReg;
    37 }
    38
    39 class AForm_DAG opcode, bits<6> qpReg, dag OOL, dag IOL, string asmstr,
    40 list pattern> :
    41 InstIA64 {
    42
    43 let Pattern = pattern;
    44 let Inst{5-0} = qpReg;
    45 }
    46
    47 let isBranch = 1, isTerminator = 1 in
    48 class BForm opcode, bits<6> x6, bits<3> btype, dag OOL, dag IOL, string asmstr> :
    49 InstIA64 {
    50
    51 let Inst{32-27} = x6;
    52 let Inst{8-6} = btype;
    53 }
    54
    55 class MForm opcode, bits<6> x6, dag OOL, dag IOL, string asmstr> :
    56 InstIA64 {
    57 bits<7> Ra;
    58 bits<7> Rb;
    59 bits<16> disp;
    60
    61 let Inst{35-30} = x6;
    62 // let Inst{20-16} = Rb;
    63 let Inst{15-0} = disp;
    64 }
    65
    66 class RawForm opcode, bits<26> rest, dag OOL, dag IOL, string asmstr> :
    67 InstIA64 {
    68 let Inst{25-0} = rest;
    69 }
    70
    71 // Pseudo instructions.
    72 class PseudoInstIA64 : InstIA64<0, OOL, IOL, nm> {
    73 }
    74
    75 class PseudoInstIA64_DAG pattern>
    76 : InstIA64<0, OOL, IOL, nm> {
    77 let Pattern = pattern;
    78 }
    79
    +0
    -193
    lib/Target/IA64/IA64InstrInfo.cpp less more
    None //===- IA64InstrInfo.cpp - IA64 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 IA64 implementation of the TargetInstrInfo class.
    10 //
    11 //===----------------------------------------------------------------------===//
    12
    13 #include "IA64InstrInfo.h"
    14 #include "IA64.h"
    15 #include "IA64InstrBuilder.h"
    16 #include "llvm/CodeGen/MachineInstrBuilder.h"
    17 #include "llvm/ADT/SmallVector.h"
    18 #include "llvm/Support/ErrorHandling.h"
    19 #include "IA64GenInstrInfo.inc"
    20 using namespace llvm;
    21
    22 IA64InstrInfo::IA64InstrInfo()
    23 : TargetInstrInfoImpl(IA64Insts, sizeof(IA64Insts)/sizeof(IA64Insts[0])),
    24 RI(*this) {
    25 }
    26
    27
    28 bool IA64InstrInfo::isMoveInstr(const MachineInstr& MI,
    29 unsigned& sourceReg,
    30 unsigned& destReg,
    31 unsigned& SrcSR, unsigned& DstSR) const {
    32 SrcSR = DstSR = 0; // No sub-registers.
    33
    34 unsigned oc = MI.getOpcode();
    35 if (oc == IA64::MOV || oc == IA64::FMOV) {
    36 // TODO: this doesn't detect predicate moves
    37 assert(MI.getNumOperands() >= 2 &&
    38 /* MI.getOperand(0).isReg() &&
    39 MI.getOperand(1).isReg() && */
    40 "invalid register-register move instruction");
    41 if (MI.getOperand(0).isReg() &&
    42 MI.getOperand(1).isReg()) {
    43 // if both operands of the MOV/FMOV are registers, then
    44 // yes, this is a move instruction
    45 sourceReg = MI.getOperand(1).getReg();
    46 destReg = MI.getOperand(0).getReg();
    47 return true;
    48 }
    49 }
    50 return false; // we don't consider e.g. %regN = MOV a
    51 // move instruction
    52 }
    53
    54 unsigned
    55 IA64InstrInfo::InsertBranch(MachineBasicBlock &MBB,MachineBasicBlock *TBB,
    56 MachineBasicBlock *FBB,
    57 const SmallVectorImpl &Cond)const {
    58 // FIXME this should probably have a DebugLoc argument
    59 DebugLoc dl = DebugLoc::getUnknownLoc();
    60 // Can only insert uncond branches so far.
    61 assert(Cond.empty() && !FBB && TBB && "Can only handle uncond branches!");
    62 BuildMI(&MBB, dl, get(IA64::BRL_NOTCALL)).addMBB(TBB);
    63 return 1;
    64 }
    65
    66 bool IA64InstrInfo::copyRegToReg(MachineBasicBlock &MBB,
    67 MachineBasicBlock::iterator MI,
    68 unsigned DestReg, unsigned SrcReg,
    69 const TargetRegisterClass *DestRC,
    70 const TargetRegisterClass *SrcRC) const {
    71 if (DestRC != SrcRC) {
    72 // Not yet supported!
    73 return false;
    74 }
    75
    76 DebugLoc DL = DebugLoc::getUnknownLoc();
    77 if (MI != MBB.end()) DL = MI->getDebugLoc();
    78
    79 if(DestRC == IA64::PRRegisterClass ) // if a bool, we use pseudocode
    80 // (SrcReg) DestReg = cmp.eq.unc(r0, r0)
    81 BuildMI(MBB, MI, DL, get(IA64::PCMPEQUNC), DestReg)
    82 .addReg(IA64::r0).addReg(IA64::r0).addReg(SrcReg);
    83 else // otherwise, MOV works (for both gen. regs and FP regs)
    84 BuildMI(MBB, MI, DL, get(IA64::MOV), DestReg).addReg(SrcReg);
    85
    86 return true;
    87 }
    88
    89 void IA64InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
    90 MachineBasicBlock::iterator MI,
    91 unsigned SrcReg, bool isKill,
    92 int FrameIdx,
    93 const TargetRegisterClass *RC) const{
    94 DebugLoc DL = DebugLoc::getUnknownLoc();
    95 if (MI != MBB.end()) DL = MI->getDebugLoc();
    96
    97 if (RC == IA64::FPRegisterClass) {
    98 BuildMI(MBB, MI, DL, get(IA64::STF_SPILL)).addFrameIndex(FrameIdx)
    99 .addReg(SrcReg, getKillRegState(isKill));
    100 } else if (RC == IA64::GRRegisterClass) {
    101 BuildMI(MBB, MI, DL, get(IA64::ST8)).addFrameIndex(FrameIdx)
    102 .addReg(SrcReg, getKillRegState(isKill));
    103 } else if (RC == IA64::PRRegisterClass) {
    104 /* we use IA64::r2 as a temporary register for doing this hackery. */
    105 // first we load 0:
    106 BuildMI(MBB, MI, DL, get(IA64::MOV), IA64::r2).addReg(IA64::r0);
    107 // then conditionally add 1:
    108 BuildMI(MBB, MI, DL, get(IA64::CADDIMM22), IA64::r2).addReg(IA64::r2)
    109 .addImm(1).addReg(SrcReg, getKillRegState(isKill));
    110 // and then store it to the stack
    111 BuildMI(MBB, MI, DL, get(IA64::ST8))
    112 .addFrameIndex(FrameIdx)
    113 .addReg(IA64::r2);
    114 } else
    115 llvm_unreachable("sorry, I don't know how to store this sort of reg"
    116 "in the stack");
    117 }
    118
    119 void IA64InstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
    120 bool isKill,
    121 SmallVectorImpl &Addr,
    122 const TargetRegisterClass *RC,
    123 SmallVectorImpl &NewMIs) const {
    124 unsigned Opc = 0;
    125 if (RC == IA64::FPRegisterClass) {
    126 Opc = IA64::STF8;
    127 } else if (RC == IA64::GRRegisterClass) {
    128 Opc = IA64::ST8;
    129 } else if (RC == IA64::PRRegisterClass) {
    130 Opc = IA64::ST1;
    131 } else {
    132 llvm_unreachable("sorry, I don't know how to store this sort of reg");
    133 }
    134
    135 DebugLoc DL = DebugLoc::getUnknownLoc();
    136 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc));
    137 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
    138 MIB.addOperand(Addr[i]);
    139 MIB.addReg(SrcReg, getKillRegState(isKill));
    140 NewMIs.push_back(MIB);
    141 return;
    142
    143 }
    144
    145 void IA64InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
    146 MachineBasicBlock::iterator MI,
    147 unsigned DestReg, int FrameIdx,
    148 const TargetRegisterClass *RC)const{
    149 DebugLoc DL = DebugLoc::getUnknownLoc();
    150 if (MI != MBB.end()) DL = MI->getDebugLoc();
    151
    152 if (RC == IA64::FPRegisterClass) {
    153 BuildMI(MBB, MI, DL, get(IA64::LDF_FILL), DestReg).addFrameIndex(FrameIdx);
    154 } else if (RC == IA64::GRRegisterClass) {
    155 BuildMI(MBB, MI, DL, get(IA64::LD8), DestReg).addFrameIndex(FrameIdx);
    156 } else if (RC == IA64::PRRegisterClass) {
    157 // first we load a byte from the stack into r2, our 'predicate hackery'
    158 // scratch reg
    159 BuildMI(MBB, MI, DL, get(IA64::LD8), IA64::r2).addFrameIndex(FrameIdx);
    160 // then we compare it to zero. If it _is_ zero, compare-not-equal to
    161 // r0 gives us 0, which is what we want, so that's nice.
    162 BuildMI(MBB, MI, DL, get(IA64::CMPNE), DestReg)
    163 .addReg(IA64::r2)
    164 .addReg(IA64::r0);
    165 } else {
    166 llvm_unreachable("sorry, I don't know how to load this sort of reg"
    167 "from the stack");
    168 }
    169 }
    170
    171 void IA64InstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
    172 SmallVectorImpl &Addr,
    173 const TargetRegisterClass *RC,
    174 SmallVectorImpl &NewMIs) const {
    175 unsigned Opc = 0;
    176 if (RC == IA64::FPRegisterClass) {
    177 Opc = IA64::LDF8;
    178 } else if (RC == IA64::GRRegisterClass) {
    179 Opc = IA64::LD8;
    180 } else if (RC == IA64::PRRegisterClass) {
    181 Opc = IA64::LD1;
    182 } else {
    183 llvm_unreachable("sorry, I don't know how to load this sort of reg");
    184 }
    185
    186 DebugLoc DL = DebugLoc::getUnknownLoc();
    187 MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg);
    188 for (unsigned i = 0, e = Addr.size(); i != e; ++i)
    189 MIB.addOperand(Addr[i]);
    190 NewMIs.push_back(MIB);
    191 return;
    192 }
    +0
    -70
    lib/Target/IA64/IA64InstrInfo.h less more
    None //===- IA64InstrInfo.h - IA64 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 IA64 implementation of the TargetInstrInfo class.
    10 //
    11 //===----------------------------------------------------------------------===//
    12
    13 #ifndef IA64INSTRUCTIONINFO_H
    14 #define IA64INSTRUCTIONINFO_H
    15
    16 #include "llvm/Target/TargetInstrInfo.h"
    17 #include "IA64RegisterInfo.h"
    18
    19 namespace llvm {
    20
    21 class IA64InstrInfo : public TargetInstrInfoImpl {
    22 const IA64RegisterInfo RI;
    23 public:
    24 IA64InstrInfo();
    25
    26 /// getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
    27 /// such, whenever a client has an instance of instruction info, it should
    28 /// always be able to get register info as well (through this method).
    29 ///
    30 virtual const IA64RegisterInfo &getRegisterInfo() const { return RI; }
    31
    32 /// Return true if the instruction is a register to register move and return
    33 /// the source and dest operands and their sub-register indices by reference.
    34 virtual bool isMoveInstr(const MachineInstr &MI,
    35 unsigned &SrcReg, unsigned &DstReg,
    36 unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
    37 virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
    38 MachineBasicBlock *FBB,
    39 const SmallVectorImpl &Cond) const;
    40 virtual bool copyRegToReg(MachineBasicBlock &MBB,
    41 MachineBasicBlock::iterator MI,
    42 unsigned DestReg, unsigned SrcReg,
    43 const TargetRegisterClass *DestRC,
    44 const TargetRegisterClass *SrcRC) const;
    45 virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
    46 MachineBasicBlock::iterator MI,
    47 unsigned SrcReg, bool isKill, int FrameIndex,
    48 const TargetRegisterClass *RC) const;
    49
    50 virtual void storeRegToAddr(MachineFunction &MF, unsigned SrcReg, bool isKill,
    51 SmallVectorImpl &Addr,
    52 const TargetRegisterClass *RC,
    53 SmallVectorImpl &NewMIs) const;
    54
    55 virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
    56 MachineBasicBlock::iterator MI,
    57 unsigned DestReg, int FrameIndex,
    58 const TargetRegisterClass *RC) const;
    59
    60 virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
    61 SmallVectorImpl &Addr,
    62 const TargetRegisterClass *RC,
    63 SmallVectorImpl &NewMIs) const;
    64 };
    65
    66 } // End llvm namespace
    67
    68 #endif
    69
    +0
    -751
    lib/Target/IA64/IA64InstrInfo.td less more
    None //===- IA64InstrInfo.td - Describe the IA64 Instruction Set -----*- 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 describes the IA64 instruction set, defining the instructions, and
    10 // properties of the instructions which are needed for code generation, machine
    11 // code emission, and analysis.
    12 //
    13 //===----------------------------------------------------------------------===//
    14
    15 include "IA64InstrFormats.td"
    16
    17 //===----------------------------------------------------------------------===//
    18 // IA-64 specific DAG Nodes.
    19 //
    20
    21 def IA64getfd : SDNode<"IA64ISD::GETFD", SDTFPToIntOp, []>;
    22
    23 def retflag : SDNode<"IA64ISD::RET_FLAG", SDTNone,
    24 [SDNPHasChain, SDNPOptInFlag]>;
    25
    26 //===---------
    27 // Instruction types
    28
    29 class isA { bit A=1; } // I or M unit
    30 class isM { bit M=1; } // M unit
    31 class isI { bit I=1; } // I unit
    32 class isB { bit B=1; } // B unit
    33 class isF { bit F=1; } // F unit
    34 class isLX { bit LX=1; } // I/B
    35
    36 //===---------
    37
    38 def u2imm : Operand;
    39 def u6imm : Operand;
    40 def s8imm : Operand {
    41 let PrintMethod = "printS8ImmOperand";
    42 }
    43 def s14imm : Operand {
    44 let PrintMethod = "printS14ImmOperand";
    45 }
    46 def s22imm : Operand {
    47 let PrintMethod = "printS22ImmOperand";
    48 }
    49 def u64imm : Operand {
    50 let PrintMethod = "printU64ImmOperand";
    51 }
    52 def s64imm : Operand {
    53 let PrintMethod = "printS64ImmOperand";
    54 }
    55
    56 let PrintMethod = "printGlobalOperand" in
    57 def globaladdress : Operand;
    58
    59 // the asmprinter needs to know about calls
    60 let PrintMethod = "printCallOperand" in
    61 def calltarget : Operand;
    62
    63 /* new daggy action!!! */
    64
    65 def is32ones : PatLeaf<(i64 imm), [{
    66 // is32ones predicate - True if the immediate is 0x00000000FFFFFFFF
    67 // Used to create ZXT4s appropriately
    68 uint64_t v = (uint64_t)N->getZExtValue();
    69 return (v == 0x00000000FFFFFFFFLL);
    70 }]>;
    71
    72 // isMIXable predicates - True if the immediate is
    73 // 0xFF00FF00FF00FF00, 0x00FF00FF00FF00FF
    74 // etc, through 0x00000000FFFFFFFF
    75 // Used to test for the suitability of mix*
    76 def isMIX1Lable: PatLeaf<(i64 imm), [{
    77 return((uint64_t)N->getZExtValue()==0xFF00FF00FF00FF00LL);
    78 }]>;
    79 def isMIX1Rable: PatLeaf<(i64 imm), [{
    80 return((uint64_t)N->getZExtValue()==0x00FF00FF00FF00FFLL);
    81 }]>;
    82 def isMIX2Lable: PatLeaf<(i64 imm), [{
    83 return((uint64_t)N->getZExtValue()==0xFFFF0000FFFF0000LL);
    84 }]>;
    85 def isMIX2Rable: PatLeaf<(i64 imm), [{
    86 return((uint64_t)N->getZExtValue()==0x0000FFFF0000FFFFLL);
    87 }]>;
    88 def isMIX4Lable: PatLeaf<(i64 imm), [{
    89 return((uint64_t)N->getZExtValue()==0xFFFFFFFF00000000LL);
    90 }]>;
    91 def isMIX4Rable: PatLeaf<(i64 imm), [{
    92 return((uint64_t)N->getZExtValue()==0x00000000FFFFFFFFLL);
    93 }]>;
    94
    95 def isSHLADDimm: PatLeaf<(i64 imm), [{
    96 // isSHLADDimm predicate - True if the immediate is exactly 1, 2, 3 or 4
    97 // - 0 is *not* okay.
    98 // Used to create shladd instructions appropriately
    99 int64_t v = (int64_t)N->getZExtValue();
    100 return (v >= 1 && v <= 4);
    101 }]>;
    102
    103 def immSExt14 : PatLeaf<(i64 imm), [{
    104 // immSExt14 predicate - True if the immediate fits in a 14-bit sign extended
    105 // field. Used by instructions like 'adds'.
    106 int64_t v = (int64_t)N->getZExtValue();
    107 return (v <= 8191 && v >= -8192);
    108 }]>;
    109
    110 // imm64 predicate - True if the immediate fits in a 64-bit
    111 // field - i.e., true. used to keep movl happy
    112 def imm64 : PatLeaf<(i64 imm)>;
    113
    114 def ADD : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    115 "add $dst = $src1, $src2",
    116 [(set GR:$dst, (add GR:$src1, GR:$src2))]>, isA;
    117
    118 def ADD1 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    119 "add $dst = $src1, $src2, 1",
    120 [(set GR:$dst, (add (add GR:$src1, GR:$src2), 1))]>, isA;
    121
    122 def ADDS : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, s14imm:$imm),
    123 "adds $dst = $imm, $src1",
    124 [(set GR:$dst, (add GR:$src1, immSExt14:$imm))]>, isA;
    125
    126 def MOVL : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins s64imm:$imm),
    127 "movl $dst = $imm",
    128 [(set GR:$dst, imm64:$imm)]>, isLX;
    129
    130 def ADDL_GA : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, globaladdress:$imm),
    131 "addl $dst = $imm, $src1",
    132 []>, isA;
    133
    134 // hmm
    135 def ADDL_EA : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, calltarget:$imm),
    136 "addl $dst = $imm, $src1",
    137 []>, isA;
    138
    139 def SUB : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    140 "sub $dst = $src1, $src2",
    141 [(set GR:$dst, (sub GR:$src1, GR:$src2))]>, isA;
    142
    143 def SUB1 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    144 "sub $dst = $src1, $src2, 1",
    145 [(set GR:$dst, (add (sub GR: $src1, GR:$src2), -1))]>, isA;
    146
    147 let isTwoAddress = 1 in {
    148 def TPCADDIMM22 : AForm<0x03, 0x0b,
    149 (outs GR:$dst), (ins GR:$src1, s22imm:$imm, PR:$qp),
    150 "($qp) add $dst = $imm, $dst">, isA;
    151 def TPCADDS : AForm_DAG<0x03, 0x0b,
    152 (outs GR:$dst), (ins GR:$src1, s14imm:$imm, PR:$qp),
    153 "($qp) adds $dst = $imm, $dst",
    154 []>, isA;
    155 def TPCMPIMM8NE : AForm<0x03, 0x0b,
    156 (outs PR:$dst), (ins PR:$src1, s22imm:$imm, GR:$src2, PR:$qp),
    157 "($qp) cmp.ne $dst , p0 = $imm, $src2">, isA;
    158 }
    159
    160 // zero extend a bool (predicate reg) into an integer reg
    161 def ZXTb : Pat<(zext PR:$src),
    162 (TPCADDIMM22 (ADDS r0, 0), 1, PR:$src)>;
    163 def AXTb : Pat<(anyext PR:$src),
    164 (TPCADDIMM22 (ADDS r0, 0), 1, PR:$src)>;
    165
    166 // normal sign/zero-extends
    167 def SXT1 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "sxt1 $dst = $src",
    168 [(set GR:$dst, (sext_inreg GR:$src, i8))]>, isI;
    169 def ZXT1 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "zxt1 $dst = $src",
    170 [(set GR:$dst, (and GR:$src, 255))]>, isI;
    171 def SXT2 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "sxt2 $dst = $src",
    172 [(set GR:$dst, (sext_inreg GR:$src, i16))]>, isI;
    173 def ZXT2 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "zxt2 $dst = $src",
    174 [(set GR:$dst, (and GR:$src, 65535))]>, isI;
    175 def SXT4 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "sxt4 $dst = $src",
    176 [(set GR:$dst, (sext_inreg GR:$src, i32))]>, isI;
    177 def ZXT4 : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "zxt4 $dst = $src",
    178 [(set GR:$dst, (and GR:$src, is32ones))]>, isI;
    179
    180 // fixme: shrs vs shru?
    181 def MIX1L : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    182 "mix1.l $dst = $src1, $src2",
    183 [(set GR:$dst, (or (and GR:$src1, isMIX1Lable),
    184 (and (srl GR:$src2, (i64 8)), isMIX1Lable)))]>, isI;
    185
    186 def MIX2L : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    187 "mix2.l $dst = $src1, $src2",
    188 [(set GR:$dst, (or (and GR:$src1, isMIX2Lable),
    189 (and (srl GR:$src2, (i64 16)), isMIX2Lable)))]>, isI;
    190
    191 def MIX4L : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    192 "mix4.l $dst = $src1, $src2",
    193 [(set GR:$dst, (or (and GR:$src1, isMIX4Lable),
    194 (and (srl GR:$src2, (i64 32)), isMIX4Lable)))]>, isI;
    195
    196 def MIX1R : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    197 "mix1.r $dst = $src1, $src2",
    198 [(set GR:$dst, (or (and (shl GR:$src1, (i64 8)), isMIX1Rable),
    199 (and GR:$src2, isMIX1Rable)))]>, isI;
    200
    201 def MIX2R : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    202 "mix2.r $dst = $src1, $src2",
    203 [(set GR:$dst, (or (and (shl GR:$src1, (i64 16)), isMIX2Rable),
    204 (and GR:$src2, isMIX2Rable)))]>, isI;
    205
    206 def MIX4R : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    207 "mix4.r $dst = $src1, $src2",
    208 [(set GR:$dst, (or (and (shl GR:$src1, (i64 32)), isMIX4Rable),
    209 (and GR:$src2, isMIX4Rable)))]>, isI;
    210
    211 def GETFSIGD : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins FP:$src),
    212 "getf.sig $dst = $src",
    213 []>, isM;
    214
    215 def SETFSIGD : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins GR:$src),
    216 "setf.sig $dst = $src",
    217 []>, isM;
    218
    219 def XMALD : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3),
    220 "xma.l $dst = $src1, $src2, $src3",
    221 []>, isF;
    222 def XMAHD : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3),
    223 "xma.h $dst = $src1, $src2, $src3",
    224 []>, isF;
    225 def XMAHUD : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3),
    226 "xma.hu $dst = $src1, $src2, $src3",
    227 []>, isF;
    228
    229 // pseudocode for integer multiplication
    230 def : Pat<(mul GR:$src1, GR:$src2),
    231 (GETFSIGD (XMALD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>;
    232 def : Pat<(mulhs GR:$src1, GR:$src2),
    233 (GETFSIGD (XMAHD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>;
    234 def : Pat<(mulhu GR:$src1, GR:$src2),
    235 (GETFSIGD (XMAHUD (SETFSIGD GR:$src1), (SETFSIGD GR:$src2), F0))>;
    236
    237 // TODO: addp4 (addp4 dst = src, r0 is a 32-bit add)
    238 // has imm form, too
    239
    240 // def ADDS : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, s14imm:$imm),
    241 // "adds $dst = $imm, $src1">;
    242
    243 def AND : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    244 "and $dst = $src1, $src2",
    245 [(set GR:$dst, (and GR:$src1, GR:$src2))]>, isA;
    246 def ANDCM : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    247 "andcm $dst = $src1, $src2",
    248 [(set GR:$dst, (and GR:$src1, (not GR:$src2)))]>, isA;
    249 // TODO: and/andcm/or/xor/add/sub/shift immediate forms
    250 def OR : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    251 "or $dst = $src1, $src2",
    252 [(set GR:$dst, (or GR:$src1, GR:$src2))]>, isA;
    253
    254 def pOR : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2, PR:$qp),
    255 "($qp) or $dst = $src1, $src2">, isA;
    256
    257 // the following are all a bit unfortunate: we throw away the complement
    258 // of the compare!
    259 def CMPEQ : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2),
    260 "cmp.eq $dst, p0 = $src1, $src2",
    261 [(set PR:$dst, (seteq GR:$src1, GR:$src2))]>, isA;
    262 def CMPGT : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2),
    263 "cmp.gt $dst, p0 = $src1, $src2",
    264 [(set PR:$dst, (setgt GR:$src1, GR:$src2))]>, isA;
    265 def CMPGE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2),
    266 "cmp.ge $dst, p0 = $src1, $src2",
    267 [(set PR:$dst, (setge GR:$src1, GR:$src2))]>, isA;
    268 def CMPLT : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2),
    269 "cmp.lt $dst, p0 = $src1, $src2",
    270 [(set PR:$dst, (setlt GR:$src1, GR:$src2))]>, isA;
    271 def CMPLE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2),
    272 "cmp.le $dst, p0 = $src1, $src2",
    273 [(set PR:$dst, (setle GR:$src1, GR:$src2))]>, isA;
    274 def CMPNE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2),
    275 "cmp.ne $dst, p0 = $src1, $src2",
    276 [(set PR:$dst, (setne GR:$src1, GR:$src2))]>, isA;
    277 def CMPLTU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2),
    278 "cmp.ltu $dst, p0 = $src1, $src2",
    279 [(set PR:$dst, (setult GR:$src1, GR:$src2))]>, isA;
    280 def CMPGTU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2),
    281 "cmp.gtu $dst, p0 = $src1, $src2",
    282 [(set PR:$dst, (setugt GR:$src1, GR:$src2))]>, isA;
    283 def CMPLEU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2),
    284 "cmp.leu $dst, p0 = $src1, $src2",
    285 [(set PR:$dst, (setule GR:$src1, GR:$src2))]>, isA;
    286 def CMPGEU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2),
    287 "cmp.geu $dst, p0 = $src1, $src2",
    288 [(set PR:$dst, (setuge GR:$src1, GR:$src2))]>, isA;
    289
    290 // and we do the whole thing again for FP compares!
    291 def FCMPEQ : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2),
    292 "fcmp.eq $dst, p0 = $src1, $src2",
    293 [(set PR:$dst, (seteq FP:$src1, FP:$src2))]>, isF;
    294 def FCMPGT : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2),
    295 "fcmp.gt $dst, p0 = $src1, $src2",
    296 [(set PR:$dst, (setgt FP:$src1, FP:$src2))]>, isF;
    297 def FCMPGE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2),
    298 "fcmp.ge $dst, p0 = $src1, $src2",
    299 [(set PR:$dst, (setge FP:$src1, FP:$src2))]>, isF;
    300 def FCMPLT : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2),
    301 "fcmp.lt $dst, p0 = $src1, $src2",
    302 [(set PR:$dst, (setlt FP:$src1, FP:$src2))]>, isF;
    303 def FCMPLE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2),
    304 "fcmp.le $dst, p0 = $src1, $src2",
    305 [(set PR:$dst, (setle FP:$src1, FP:$src2))]>, isF;
    306 def FCMPNE : AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2),
    307 "fcmp.neq $dst, p0 = $src1, $src2",
    308 [(set PR:$dst, (setne FP:$src1, FP:$src2))]>, isF;
    309 def FCMPLTU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2),
    310 "fcmp.lt $dst, p0 = $src1, $src2",
    311 [(set PR:$dst, (setult FP:$src1, FP:$src2))]>, isF;
    312 def FCMPGTU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2),
    313 "fcmp.gt $dst, p0 = $src1, $src2",
    314 [(set PR:$dst, (setugt FP:$src1, FP:$src2))]>, isF;
    315 def FCMPLEU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2),
    316 "fcmp.le $dst, p0 = $src1, $src2",
    317 [(set PR:$dst, (setule FP:$src1, FP:$src2))]>, isF;
    318 def FCMPGEU: AForm_DAG<0x03, 0x0b, (outs PR:$dst), (ins FP:$src1, FP:$src2),
    319 "fcmp.ge $dst, p0 = $src1, $src2",
    320 [(set PR:$dst, (setuge FP:$src1, FP:$src2))]>, isF;
    321
    322 def PCMPEQUNCR0R0 : AForm<0x03, 0x0b, (outs PR:$dst), (ins PR:$qp),
    323 "($qp) cmp.eq.unc $dst, p0 = r0, r0">, isA;
    324
    325 def : Pat<(trunc GR:$src), // truncate i64 to i1
    326 (CMPNE GR:$src, r0)>; // $src!=0? If so, PR:$dst=true
    327
    328 let isTwoAddress=1 in {
    329 def TPCMPEQR0R0 : AForm<0x03, 0x0b, (outs PR:$dst), (ins PR:$bogus, PR:$qp),
    330 "($qp) cmp.eq $dst, p0 = r0, r0">, isA;
    331 def TPCMPNER0R0 : AForm<0x03, 0x0b, (outs PR:$dst), (ins PR:$bogus, PR:$qp),
    332 "($qp) cmp.ne $dst, p0 = r0, r0">, isA;
    333 }
    334
    335 /* our pseudocode for OR on predicates is:
    336 pC = pA OR pB
    337 -------------
    338 (pA) cmp.eq.unc pC,p0 = r0,r0 // pC = pA
    339 ;;
    340 (pB) cmp.eq pC,p0 = r0,r0 // if (pB) pC = 1 */
    341
    342 def bOR : Pat<(or PR:$src1, PR:$src2),
    343 (TPCMPEQR0R0 (PCMPEQUNCR0R0 PR:$src1), PR:$src2)>;
    344
    345 /* our pseudocode for AND on predicates is:
    346 *
    347 (pA) cmp.eq.unc pC,p0 = r0,r0 // pC = pA
    348 cmp.eq pTemp,p0 = r0,r0 // pTemp = NOT pB
    349 ;;
    350 (pB) cmp.ne pTemp,p0 = r0,r0
    351 ;;
    352 (pTemp)cmp.ne pC,p0 = r0,r0 // if (NOT pB) pC = 0 */
    353
    354 def bAND : Pat<(and PR:$src1, PR:$src2),
    355 ( TPCMPNER0R0 (PCMPEQUNCR0R0 PR:$src1),
    356 (TPCMPNER0R0 (CMPEQ r0, r0), PR:$src2) )>;
    357
    358 /* one possible routine for XOR on predicates is:
    359
    360 // Compute px = py ^ pz
    361 // using sum of products: px = (py & !pz) | (pz & !py)
    362 // Uses 5 instructions in 3 cycles.
    363 // cycle 1
    364 (pz) cmp.eq.unc px = r0, r0 // px = pz
    365 (py) cmp.eq.unc pt = r0, r0 // pt = py
    366 ;;
    367 // cycle 2
    368 (pt) cmp.ne.and px = r0, r0 // px = px & !pt (px = pz & !pt)
    369 (pz) cmp.ne.and pt = r0, r0 // pt = pt & !pz
    370 ;;
    371 } { .mmi
    372 // cycle 3
    373 (pt) cmp.eq.or px = r0, r0 // px = px | pt
    374
    375 *** Another, which we use here, requires one scratch GR. it is:
    376
    377 mov rt = 0 // initialize rt off critical path
    378 ;;
    379
    380 // cycle 1
    381 (pz) cmp.eq.unc px = r0, r0 // px = pz
    382 (pz) mov rt = 1 // rt = pz
    383 ;;
    384 // cycle 2
    385 (py) cmp.ne px = 1, rt // if (py) px = !pz
    386
    387 .. these routines kindly provided by Jim Hull
    388 */
    389
    390 def bXOR : Pat<(xor PR:$src1, PR:$src2),
    391 (TPCMPIMM8NE (PCMPEQUNCR0R0 PR:$src2), 1,
    392 (TPCADDS (ADDS r0, 0), 1, PR:$src2),
    393 PR:$src1)>;
    394
    395 def XOR : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    396 "xor $dst = $src1, $src2",
    397 [(set GR:$dst, (xor GR:$src1, GR:$src2))]>, isA;
    398
    399 def SHLADD: AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1,s64imm:$imm,GR:$src2),
    400 "shladd $dst = $src1, $imm, $src2",
    401 [(set GR:$dst, (add GR:$src2, (shl GR:$src1, isSHLADDimm:$imm)))]>, isA;
    402
    403 def SHL : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    404 "shl $dst = $src1, $src2",
    405 [(set GR:$dst, (shl GR:$src1, GR:$src2))]>, isI;
    406
    407 def SHRU : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    408 "shr.u $dst = $src1, $src2",
    409 [(set GR:$dst, (srl GR:$src1, GR:$src2))]>, isI;
    410
    411 def SHRS : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, GR:$src2),
    412 "shr $dst = $src1, $src2",
    413 [(set GR:$dst, (sra GR:$src1, GR:$src2))]>, isI;
    414
    415 def MOV : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src), "mov $dst = $src">, isA;
    416 def FMOV : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    417 "mov $dst = $src">, isF; // XXX: there _is_ no fmov
    418 def PMOV : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src, PR:$qp),
    419 "($qp) mov $dst = $src">, isA;
    420
    421 def SPILL_ALL_PREDICATES_TO_GR : AForm<0x03, 0x0b, (outs GR:$dst), (ins),
    422 "mov $dst = pr">, isI;
    423 def FILL_ALL_PREDICATES_FROM_GR : AForm<0x03, 0x0b, (outs), (ins GR:$src),
    424 "mov pr = $src">, isI;
    425
    426 let isTwoAddress = 1 in {
    427 def CMOV : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src2, GR:$src, PR:$qp),
    428 "($qp) mov $dst = $src">, isA;
    429 }
    430
    431 def PFMOV : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src, PR:$qp),
    432 "($qp) mov $dst = $src">, isF;
    433
    434 let isTwoAddress = 1 in {
    435 def CFMOV : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src2, FP:$src, PR:$qp),
    436 "($qp) mov $dst = $src">, isF;
    437 }
    438
    439 def SELECTINT : Pat<(select PR:$which, GR:$src1, GR:$src2),
    440 (CMOV (MOV GR:$src2), GR:$src1, PR:$which)>; // note order!
    441 def SELECTFP : Pat<(select PR:$which, FP:$src1, FP:$src2),
    442 (CFMOV (FMOV FP:$src2), FP:$src1, PR:$which)>; // note order!
    443 // TODO: can do this faster, w/o using any integer regs (see pattern isel)
    444 def SELECTBOOL : Pat<(select PR:$which, PR:$src1, PR:$src2), // note order!
    445 (CMPNE (CMOV
    446 (MOV (TPCADDIMM22 (ADDS r0, 0), 1, PR:$src2)),
    447 (TPCADDIMM22 (ADDS r0, 0), 1, PR:$src1), PR:$which), r0)>;
    448
    449 // load constants of various sizes // FIXME: prettyprint -ve constants
    450 def : Pat<(i64 immSExt14:$imm), (ADDS r0, immSExt14:$imm)>;
    451 def : Pat<(i1 -1), (CMPEQ r0, r0)>; // TODO: this should just be a ref to p0
    452 def : Pat<(i1 0), (CMPNE r0, r0)>; // TODO: any instruction actually *using*
    453 // this predicate should be killed!
    454
    455 // TODO: support postincrement (reg, imm9) loads+stores - this needs more
    456 // tablegen support
    457
    458 def IUSE : PseudoInstIA64<(outs), (ins variable_ops), "// IUSE">;
    459 def ADJUSTCALLSTACKUP : PseudoInstIA64<(outs), (ins variable_ops),
    460 "// ADJUSTCALLSTACKUP">;
    461 def ADJUSTCALLSTACKDOWN : PseudoInstIA64<(outs), (ins variable_ops),
    462 "// ADJUSTCALLSTACKDOWN">;
    463 def PSEUDO_ALLOC : PseudoInstIA64<(outs), (ins GR:$foo), "// PSEUDO_ALLOC">;
    464
    465 def ALLOC : AForm<0x03, 0x0b,
    466 (outs GR:$dst), (ins i8imm:$inputs, i8imm:$locals, i8imm:$outputs, i8imm:$rotating),
    467 "alloc $dst = ar.pfs,$inputs,$locals,$outputs,$rotating">, isM;
    468
    469 let isTwoAddress = 1 in {
    470 def TCMPNE : AForm<0x03, 0x0b,
    471 (outs PR:$dst), (ins PR:$src2, GR:$src3, GR:$src4),
    472 "cmp.ne $dst, p0 = $src3, $src4">, isA;
    473
    474 def TPCMPEQOR : AForm<0x03, 0x0b,
    475 (outs PR:$dst), (ins PR:$src2, GR:$src3, GR:$src4, PR:$qp),
    476 "($qp) cmp.eq.or $dst, p0 = $src3, $src4">, isA;
    477
    478 def TPCMPNE : AForm<0x03, 0x0b,
    479 (outs PR:$dst), (ins PR:$src2, GR:$src3, GR:$src4, PR:$qp),
    480 "($qp) cmp.ne $dst, p0 = $src3, $src4">, isA;
    481
    482 def TPCMPEQ : AForm<0x03, 0x0b,
    483 (outs PR:$dst), (ins PR:$src2, GR:$src3, GR:$src4, PR:$qp),
    484 "($qp) cmp.eq $dst, p0 = $src3, $src4">, isA;
    485 }
    486
    487 def MOVSIMM14 : AForm<0x03, 0x0b, (outs GR:$dst), (ins s14imm:$imm),
    488 "mov $dst = $imm">, isA;
    489 def MOVSIMM22 : AForm<0x03, 0x0b, (outs GR:$dst), (ins s22imm:$imm),
    490 "mov $dst = $imm">, isA;
    491 def MOVLIMM64 : AForm<0x03, 0x0b, (outs GR:$dst), (ins s64imm:$imm),
    492 "movl $dst = $imm">, isLX;
    493
    494 def SHLI : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, u6imm:$imm),
    495 "shl $dst = $src1, $imm">, isI;
    496 def SHRUI : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, u6imm:$imm),
    497 "shr.u $dst = $src1, $imm">, isI;
    498 def SHRSI : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, u6imm:$imm),
    499 "shr $dst = $src1, $imm">, isI;
    500
    501 def EXTRU : AForm<0x03, 0x0b,
    502 (outs GR:$dst), (ins GR:$src1, u6imm:$imm1, u6imm:$imm2),
    503 "extr.u $dst = $src1, $imm1, $imm2">, isI;
    504
    505 def DEPZ : AForm<0x03, 0x0b,
    506 (outs GR:$dst), (ins GR:$src1, u6imm:$imm1, u6imm:$imm2),
    507 "dep.z $dst = $src1, $imm1, $imm2">, isI;
    508
    509 def PCMPEQOR : AForm<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2, PR:$qp),
    510 "($qp) cmp.eq.or $dst, p0 = $src1, $src2">, isA;
    511 def PCMPEQUNC : AForm<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2, PR:$qp),
    512 "($qp) cmp.eq.unc $dst, p0 = $src1, $src2">, isA;
    513 def PCMPNE : AForm<0x03, 0x0b, (outs PR:$dst), (ins GR:$src1, GR:$src2, PR:$qp),
    514 "($qp) cmp.ne $dst, p0 = $src1, $src2">, isA;
    515
    516 // two destinations!
    517 def BCMPEQ : AForm<0x03, 0x0b, (outs PR:$dst1, PR:$dst2), (ins GR:$src1, GR:$src2),
    518 "cmp.eq $dst1, dst2 = $src1, $src2">, isA;
    519
    520 def ADDIMM14 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, s14imm:$imm),
    521 "adds $dst = $imm, $src1">, isA;
    522
    523 def ADDIMM22 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, s22imm:$imm),
    524 "add $dst = $imm, $src1">, isA;
    525 def CADDIMM22 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$src1, s22imm:$imm, PR:$qp),
    526 "($qp) add $dst = $imm, $src1">, isA;
    527
    528 def SUBIMM8 : AForm<0x03, 0x0b, (outs GR:$dst), (ins s8imm:$imm, GR:$src2),
    529 "sub $dst = $imm, $src2">, isA;
    530
    531 let mayStore = 1 in {
    532 def ST1 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, GR:$value),
    533 "st1 [$dstPtr] = $value">, isM;
    534 def ST2 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, GR:$value),
    535 "st2 [$dstPtr] = $value">, isM;
    536 def ST4 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, GR:$value),
    537 "st4 [$dstPtr] = $value">, isM;
    538 def ST8 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, GR:$value),
    539 "st8 [$dstPtr] = $value">, isM;
    540 def STF4 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, FP:$value),
    541 "stfs [$dstPtr] = $value">, isM;
    542 def STF8 : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, FP:$value),
    543 "stfd [$dstPtr] = $value">, isM;
    544 def STF_SPILL : AForm<0x03, 0x0b, (outs), (ins GR:$dstPtr, FP:$value),
    545 "stf.spill [$dstPtr] = $value">, isM;
    546 }
    547
    548 let canFoldAsLoad = 1 in {
    549 def LD1 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$srcPtr),
    550 "ld1 $dst = [$srcPtr]">, isM;
    551 def LD2 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$srcPtr),
    552 "ld2 $dst = [$srcPtr]">, isM;
    553 def LD4 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$srcPtr),
    554 "ld4 $dst = [$srcPtr]">, isM;
    555 def LD8 : AForm<0x03, 0x0b, (outs GR:$dst), (ins GR:$srcPtr),
    556 "ld8 $dst = [$srcPtr]">, isM;
    557 def LDF4 : AForm<0x03, 0x0b, (outs FP:$dst), (ins GR:$srcPtr),
    558 "ldfs $dst = [$srcPtr]">, isM;
    559 def LDF8 : AForm<0x03, 0x0b, (outs FP:$dst), (ins GR:$srcPtr),
    560 "ldfd $dst = [$srcPtr]">, isM;
    561 def LDF_FILL : AForm<0x03, 0x0b, (outs FP:$dst), (ins GR:$srcPtr),
    562 "ldf.fill $dst = [$srcPtr]">, isM;
    563 }
    564
    565 def POPCNT : AForm_DAG<0x03, 0x0b, (outs GR:$dst), (ins GR:$src),
    566 "popcnt $dst = $src",
    567 [(set GR:$dst, (ctpop GR:$src))]>, isI;
    568
    569 // some FP stuff: // TODO: single-precision stuff?
    570 def FADD : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2),
    571 "fadd $dst = $src1, $src2",
    572 [(set FP:$dst, (fadd FP:$src1, FP:$src2))]>, isF;
    573 def FADDS: AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2),
    574 "fadd.s $dst = $src1, $src2">, isF;
    575 def FSUB : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2),
    576 "fsub $dst = $src1, $src2",
    577 [(set FP:$dst, (fsub FP:$src1, FP:$src2))]>, isF;
    578 def FMPY : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2),
    579 "fmpy $dst = $src1, $src2",
    580 [(set FP:$dst, (fmul FP:$src1, FP:$src2))]>, isF;
    581 def FMA : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3),
    582 "fma $dst = $src1, $src2, $src3",
    583 [(set FP:$dst, (fadd (fmul FP:$src1, FP:$src2), FP:$src3))]>, isF;
    584 def FMS : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3),
    585 "fms $dst = $src1, $src2, $src3",
    586 [(set FP:$dst, (fsub (fmul FP:$src1, FP:$src2), FP:$src3))]>, isF;
    587 def FNMA : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3),
    588 "fnma $dst = $src1, $src2, $src3",
    589 [(set FP:$dst, (fneg (fadd (fmul FP:$src1, FP:$src2), FP:$src3)))]>, isF;
    590 def FABS : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    591 "fabs $dst = $src",
    592 [(set FP:$dst, (fabs FP:$src))]>, isF;
    593 def FNEG : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    594 "fneg $dst = $src",
    595 [(set FP:$dst, (fneg FP:$src))]>, isF;
    596 def FNEGABS : AForm_DAG<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    597 "fnegabs $dst = $src",
    598 [(set FP:$dst, (fneg (fabs FP:$src)))]>, isF;
    599
    600 let isTwoAddress=1 in {
    601 def TCFMAS1 : AForm<0x03, 0x0b,
    602 (outs FP:$dst), (ins FP:$bogussrc, FP:$src1, FP:$src2, FP:$src3, PR:$qp),
    603 "($qp) fma.s1 $dst = $src1, $src2, $src3">, isF;
    604 def TCFMADS0 : AForm<0x03, 0x0b,
    605 (outs FP:$dst), (ins FP:$bogussrc, FP:$src1, FP:$src2, FP:$src3, PR:$qp),
    606 "($qp) fma.d.s0 $dst = $src1, $src2, $src3">, isF;
    607 }
    608
    609 def CFMAS1 : AForm<0x03, 0x0b,
    610 (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3, PR:$qp),
    611 "($qp) fma.s1 $dst = $src1, $src2, $src3">, isF;
    612 def CFNMAS1 : AForm<0x03, 0x0b,
    613 (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3, PR:$qp),
    614 "($qp) fnma.s1 $dst = $src1, $src2, $src3">, isF;
    615
    616 def CFMADS1 : AForm<0x03, 0x0b,
    617 (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3, PR:$qp),
    618 "($qp) fma.d.s1 $dst = $src1, $src2, $src3">, isF;
    619 def CFMADS0 : AForm<0x03, 0x0b,
    620 (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3, PR:$qp),
    621 "($qp) fma.d.s0 $dst = $src1, $src2, $src3">, isF;
    622 def CFNMADS1 : AForm<0x03, 0x0b,
    623 (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3, PR:$qp),
    624 "($qp) fnma.d.s1 $dst = $src1, $src2, $src3">, isF;
    625
    626 def FRCPAS0 : AForm<0x03, 0x0b, (outs FP:$dstFR, PR:$dstPR), (ins FP:$src1, FP:$src2),
    627 "frcpa.s0 $dstFR, $dstPR = $src1, $src2">, isF;
    628 def FRCPAS1 : AForm<0x03, 0x0b, (outs FP:$dstFR, PR:$dstPR), (ins FP:$src1, FP:$src2),
    629 "frcpa.s1 $dstFR, $dstPR = $src1, $src2">, isF;
    630
    631 def XMAL : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src1, FP:$src2, FP:$src3),
    632 "xma.l $dst = $src1, $src2, $src3">, isF;
    633
    634 def FCVTXF : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    635 "fcvt.xf $dst = $src">, isF;
    636 def FCVTXUF : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    637 "fcvt.xuf $dst = $src">, isF;
    638 def FCVTXUFS1 : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    639 "fcvt.xuf.s1 $dst = $src">, isF;
    640 def FCVTFX : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    641 "fcvt.fx $dst = $src">, isF;
    642 def FCVTFXU : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    643 "fcvt.fxu $dst = $src">, isF;
    644
    645 def FCVTFXTRUNC : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    646 "fcvt.fx.trunc $dst = $src">, isF;
    647 def FCVTFXUTRUNC : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    648 "fcvt.fxu.trunc $dst = $src">, isF;
    649
    650 def FCVTFXTRUNCS1 : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    651 "fcvt.fx.trunc.s1 $dst = $src">, isF;
    652 def FCVTFXUTRUNCS1 : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    653 "fcvt.fxu.trunc.s1 $dst = $src">, isF;
    654
    655 def FNORMD : AForm<0x03, 0x0b, (outs FP:$dst), (ins FP:$src),
    656 "fnorm.d $dst = $src">, isF;
    657
    658 def GETFD : AForm<0x03, 0x0b, (outs GR:$dst), (ins FP:$src),
    659 "getf.d $dst = $src">, isM;
    660 def SETFD : AForm<0x03, 0x0b, (outs FP:$dst), (ins GR:$src),
    661 "setf.d $dst = $src">, isM;
    662
    663 def GETFSIG : AForm<0x03, 0x0b, (outs GR:$dst), (ins FP:$src),
    664 "getf.sig $dst = $src">, isM;
    665 def SETFSIG : AForm<0x03, 0x0b, (outs FP:$dst), (ins GR:$src),
    666 "setf.sig $dst = $src">, isM;
    667
    668 // these four FP<->int conversion patterns need checking/cleaning
    669 def SINT_TO_FP : Pat<(sint_to_fp GR:$src),
    670 (FNORMD (FCVTXF (SETFSIG GR:$src)))>;
    671 def UINT_TO_FP : Pat<(uint_to_fp GR:$src),
    672 (FNORMD (FCVTXUF (SETFSIG GR:$src)))>;
    673 def FP_TO_SINT : Pat<(i64 (fp_to_sint FP:$src)),
    674 (GETFSIG (FCVTFXTRUNC FP:$src))>;
    675 def FP_TO_UINT : Pat<(i64 (fp_to_uint FP:$src)),
    676 (GETFSIG (FCVTFXUTRUNC FP:$src))>;
    677
    678 def fpimm0 : PatLeaf<(fpimm), [{
    679 return N->isExactlyValue(+0.0);
    680 }]>;
    681 def fpimm1 : PatLeaf<(fpimm), [{
    682 return N->isExactlyValue(+1.0);
    683 }]>;
    684 def fpimmn0 : PatLeaf<(fpimm), [{
    685 return N->isExactlyValue(-0.0);
    686 }]>;
    687 def fpimmn1 : PatLeaf<(fpimm), [{
    688 return N->isExactlyValue(-1.0);
    689 }]>;
    690
    691 def : Pat<(f64 fpimm0), (FMOV F0)>;
    692 def : Pat<(f64 fpimm1), (FMOV F1)>;
    693 def : Pat<(f64 fpimmn0), (FNEG F0)>;
    694 def : Pat<(f64 fpimmn1), (FNEG F1)>;
    695
    696 let isTerminator = 1, isBranch = 1 in {
    697 def BRL_NOTCALL : RawForm<0x03, 0xb0, (outs), (ins i64imm:$dst),
    698 "(p0) brl.cond.sptk $dst">, isB;
    699 def BRLCOND_NOTCALL : RawForm<0x03, 0xb0, (outs), (ins PR:$qp, i64imm:$dst),
    700 "($qp) brl.cond.sptk $dst">, isB;
    701 def BRCOND_NOTCALL : RawForm<0x03, 0xb0, (outs), (ins PR:$qp, GR:$dst),
    702 "($qp) br.cond.sptk $dst">, isB;
    703 }
    704
    705 let isCall = 1, /* isTerminator = 1, isBranch = 1, */
    706 Uses = [out0,out1,out2,out3,out4,out5,out6,out7],
    707 // all calls clobber non-callee-saved registers, and for now, they are these:
    708 Defs = [r2,r3,r8,r9,r10,r11,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,
    709 r25,r26,r27,r28,r29,r30,r31,
    710 p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,
    711 F6,F7,F8,F9,F10,F11,F12,F13,F14,F15,
    712 F32,F33,F34,F35,F36,F37,F38,F39,F40,F41,F42,F43,F44,F45,F46,F47,F48,F49,
    713 F50,F51,F52,F53,F54,F55,F56,
    714 F57,F58,F59,F60,F61,F62,F63,F64,F65,F66,F67,F68,F69,F70,F71,F72,F73,F74,
    715 F75,F76,F77,F78,F79,F80,F81,
    716 F82,F83,F84,F85,F86,F87,F88,F89,F90,F91,F92,F93,F94,F95,F96,F97,F98,F99,
    717 F100,F101,F102,F103,F104,F105,
    718 F106,F107,F108,F109,F110,F111,F112,F113,F114,F115,F116,F117,F118,F119,
    719 F120,F121,F122,F123,F124,F125,F126,F127,
    720 out0,out1,out2,out3,out4,out5,out6,out7] in {
    721 // old pattern call
    722 def BRCALL: RawForm<0x03, 0xb0, (outs), (ins calltarget:$dst),
    723 "br.call.sptk rp = $dst">, isB; // FIXME: teach llvm about branch regs?
    724 // new daggy stuff!
    725
    726 // calls a globaladdress
    727 def BRCALL_IPREL_GA : RawForm<0x03, 0xb0, (outs), (ins calltarget:$dst),
    728 "br.call.sptk rp = $dst">, isB; // FIXME: teach llvm about branch regs?
    729 // calls an externalsymbol
    730 def BRCALL_IPREL_ES : RawForm<0x03, 0xb0, (outs), (ins calltarget:$dst),
    731 "br.call.sptk rp = $dst">, isB; // FIXME: teach llvm about branch regs?
    732 // calls through a function descriptor
    733 def BRCALL_INDIRECT : RawForm<0x03, 0xb0, (outs), (ins GR:$branchreg),
    734 "br.call.sptk rp = $branchreg">, isB; // FIXME: teach llvm about branch regs?
    735 def BRLCOND_CALL : RawForm<0x03, 0xb0, (outs), (ins PR:$qp, i64imm:$dst),
    736 "($qp) brl.cond.call.sptk $dst">, isB;
    737 def BRCOND_CALL : RawForm<0x03, 0xb0, (outs), (ins PR:$qp, GR:$dst),
    738 "($qp) br.cond.call.sptk $dst">, isB;
    739 }
    740
    741 // Return branch:
    742 let isTerminator = 1, isReturn = 1 in
    743 def RET : AForm_DAG<0x03, 0x0b, (outs), (ins),
    744 "br.ret.sptk.many rp",
    745 [(retflag)]>, isB; // return
    746 def : Pat<(ret), (RET)>;
    747
    748 // the evil stop bit of despair
    749 def STOP : PseudoInstIA64<(outs), (ins variable_ops), ";;">;
    750
    +0
    -34
    lib/Target/IA64/IA64MachineFunctionInfo.h less more
    None //===-- IA64MachineFunctionInfo.h - IA64-specific information ---*- C++ -*-===//
    1 //===-- for MachineFunction ---*- C++ -*-===//
    2 //
    3 // The LLVM Compiler Infrastructure
    4 //
    5 //===----------------------------------------------------------------------===//
    6 //
    7 // This file declares IA64-specific per-machine-function information.
    8 //
    9 //===----------------------------------------------------------------------===//
    10
    11 #ifndef IA64MACHINEFUNCTIONINFO_H
    12 #define IA64MACHINEFUNCTIONINFO_H
    13
    14 #include "llvm/CodeGen/MachineFunction.h"
    15 //#include "IA64JITInfo.h"
    16
    17 namespace llvm {
    18
    19 class IA64FunctionInfo : public MachineFunctionInfo {
    20
    21 public:
    22 unsigned outRegsUsed; // how many 'out' registers are used
    23 // by this machinefunction? (used to compute the appropriate
    24 // entry in the 'alloc' instruction at the top of the
    25 // machinefunction)
    26 explicit IA64FunctionInfo(MachineFunction& MF) { outRegsUsed=0; };
    27
    28 };
    29
    30 } // End llvm namespace
    31
    32 #endif
    33
    +0
    -320
    lib/Target/IA64/IA64RegisterInfo.cpp less more
    None //===- IA64RegisterInfo.cpp - IA64 Register 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 IA64 implementation of the TargetRegisterInfo class.
    10 // This file is responsible for the frame pointer elimination optimization
    11 // on IA64.
    12 //
    13 //===----------------------------------------------------------------------===//
    14
    15 #include "IA64.h"
    16 #include "IA64RegisterInfo.h"
    17 #include "IA64InstrBuilder.h"
    18 #include "IA64MachineFunctionInfo.h"
    19 #include "llvm/Constants.h"
    20 #include "llvm/Type.h"
    21 #include "llvm/CodeGen/ValueTypes.h"
    22 #include "llvm/CodeGen/MachineInstrBuilder.h"
    23 #include "llvm/CodeGen/MachineFunction.h"
    24 #include "llvm/CodeGen/MachineFrameInfo.h"
    25 #include "llvm/CodeGen/MachineLocation.h"
    26 #include "llvm/CodeGen/MachineRegisterInfo.h"
    27 #include "llvm/Support/ErrorHandling.h"
    28 #include "llvm/Target/TargetFrameInfo.h"
    29 #include "llvm/Target/TargetMachine.h"
    30 #include "llvm/Target/TargetOptions.h"
    31 #include "llvm/Target/TargetInstrInfo.h"
    32 #include "llvm/ADT/BitVector.h"
    33 #include "llvm/ADT/STLExtras.h"
    34 using namespace llvm;
    35
    36 IA64RegisterInfo::IA64RegisterInfo(const TargetInstrInfo &tii)
    37 : IA64GenRegisterInfo(IA64::ADJUSTCALLSTACKDOWN, IA64::ADJUSTCALLSTACKUP),
    38 TII(tii) {}
    39
    40 const unsigned* IA64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
    41 const {
    42 static const unsigned CalleeSavedRegs[] = {
    43 IA64::r5, 0
    44 };
    45 return CalleeSavedRegs;
    46 }
    47
    48 const TargetRegisterClass* const*
    49 IA64RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
    50 static const TargetRegisterClass * const CalleeSavedRegClasses[] = {
    51 &IA64::GRRegClass, 0
    52 };
    53 return CalleeSavedRegClasses;
    54 }
    55
    56 BitVector IA64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
    57 BitVector Reserved(getNumRegs());
    58 Reserved.set(IA64::r0);
    59 Reserved.set(IA64::r1);
    60 Reserved.set(IA64::r2);
    61 Reserved.set(IA64::r5);
    62 Reserved.set(IA64::r12);
    63 Reserved.set(IA64::r13);
    64 Reserved.set(IA64::r22);
    65 Reserved.set(IA64::rp);
    66 return Reserved;
    67 }
    68
    69 //===----------------------------------------------------------------------===//
    70 // Stack Frame Processing methods
    71 //===----------------------------------------------------------------------===//
    72
    73 // hasFP - Return true if the specified function should have a dedicated frame
    74 // pointer register. This is true if the function has variable sized allocas or
    75 // if frame pointer elimination is disabled.
    76 //
    77 bool IA64RegisterInfo::hasFP(const MachineFunction &MF) const {
    78 const MachineFrameInfo *MFI = MF.getFrameInfo();
    79 return NoFramePointerElim || MFI->hasVarSizedObjects();
    80 }
    81
    82 void IA64RegisterInfo::
    83 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
    84 MachineBasicBlock::iterator I) const {
    85 if (hasFP(MF)) {
    86 // If we have a frame pointer, turn the adjcallstackup instruction into a
    87 // 'sub SP, ' and the adjcallstackdown instruction into 'add SP,
    88 // '
    89 MachineInstr *Old = I;
    90 unsigned Amount = Old->getOperand(0).getImm();
    91 DebugLoc dl = Old->getDebugLoc();
    92 if (Amount != 0) {
    93 // We need to keep the stack aligned properly. To do this, we round the
    94 // amount of space needed for the outgoing arguments up to the next
    95 // alignment boundary.
    96 unsigned Align = MF.getTarget().getFrameInfo()->getStackAlignment();
    97 Amount = (Amount+Align-1)/Align*Align;
    98
    99 // Replace the pseudo instruction with a new instruction...
    100 if (Old->getOpcode() == IA64::ADJUSTCALLSTACKDOWN) {
    101 BuildMI(MBB, I, dl, TII.get(IA64::ADDIMM22), IA64::r12)
    102 .addReg(IA64::r12).addImm(-Amount);
    103 } else {
    104 assert(Old->getOpcode() == IA64::ADJUSTCALLSTACKUP);
    105 BuildMI(MBB, I, dl, TII.get(IA64::ADDIMM22), IA64::r12)
    106 .addReg(IA64::r12).addImm(Amount);
    107 }
    108 }
    109 }
    110
    111 MBB.erase(I);
    112 }
    113
    114 void IA64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
    115 int SPAdj, RegScavenger *RS)const{
    116 assert(SPAdj == 0 && "Unexpected");
    117
    118 unsigned i = 0;
    119 MachineInstr &MI = *II;
    120 MachineBasicBlock &MBB = *MI.getParent();
    121 MachineFunction &MF = *MBB.getParent();
    122 DebugLoc dl = MI.getDebugLoc();
    123
    124 bool FP = hasFP(MF);
    125
    126 while (!MI.getOperand(i).isFI()) {
    127 ++i;
    128 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
    129 }
    130
    131 int FrameIndex = MI.getOperand(i).getIndex();
    132
    133 // choose a base register: ( hasFP? framepointer : stack pointer )
    134 unsigned BaseRegister = FP ? IA64::r5 : IA64::r12;
    135 // Add the base register
    136 MI.getOperand(i).ChangeToRegister(BaseRegister, false);
    137
    138 // Now add the frame object offset to the offset from r1.
    139 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
    140
    141 // If we're not using a Frame Pointer that has been set to the value of the
    142 // SP before having the stack size subtracted from it, then add the stack size
    143 // to Offset to get the correct offset.
    144 Offset += MF.getFrameInfo()->getStackSize();
    145
    146 // XXX: we use 'r22' as another hack+slash temporary register here :(
    147 if (Offset <= 8191 && Offset >= -8192) { // smallish offset
    148 // Fix up the old:
    149 MI.getOperand(i).ChangeToRegister(IA64::r22, false);
    150 //insert the new
    151 BuildMI(MBB, II, dl, TII.get(IA64::ADDIMM22), IA64::r22)
    152 .addReg(BaseRegister).addImm(Offset);
    153 } else { // it's big
    154 //fix up the old:
    155 MI.getOperand(i).ChangeToRegister(IA64::r22, false);
    156 BuildMI(MBB, II, dl, TII.get(IA64::MOVLIMM64), IA