Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 2 commits
  • 1,143 files changed
  • 0 commit comments
  • 1 contributor
Showing with 5,682 additions and 3,681 deletions.
  1. +1 −1 CMakeLists.txt
  2. +0 −2 autoconf/config.sub
  3. +6 −6 autoconf/configure.ac
  4. +5 −5 configure
  5. +1 −1 include/llvm/ADT/Triple.h
  6. +1 −1 include/llvm/Support/ELF.h
  7. +6 −6 lib/Support/Triple.cpp
  8. +1 −1 lib/Target/LLVMBuild.txt
  9. +31 −0 lib/Target/LM32/CMakeLists.txt
  10. +35 −0 lib/Target/LM32/LLVMBuild.txt
  11. +40 −0 lib/Target/LM32/LM32.h
  12. +77 −0 lib/Target/LM32/LM32.td
  13. +223 −0 lib/Target/LM32/LM32AsmPrinter.cpp
  14. +50 −0 lib/Target/LM32/LM32CallingConv.td
  15. +117 −0 lib/Target/LM32/LM32ELFWriterInfo.cpp
  16. +58 −0 lib/Target/LM32/LM32ELFWriterInfo.h
  17. +410 −0 lib/Target/LM32/LM32FrameLowering.cpp
  18. +85 −0 lib/Target/LM32/LM32FrameLowering.h
  19. +278 −0 lib/Target/LM32/LM32ISelDAGToDAG.cpp
  20. +1,014 −0 lib/Target/LM32/LM32ISelLowering.cpp
  21. +194 −0 lib/Target/LM32/LM32ISelLowering.h
  22. +227 −0 lib/Target/LM32/LM32InstrFormats.td
  23. +374 −0 lib/Target/LM32/LM32InstrInfo.cpp
  24. +135 −0 lib/Target/LM32/LM32InstrInfo.h
  25. +628 −0 lib/Target/LM32/LM32InstrInfo.td
  26. +69 −0 lib/Target/LM32/LM32MachineFunctionInfo.h
  27. +289 −0 lib/Target/LM32/LM32RegisterInfo.cpp
  28. +81 −0 lib/Target/LM32/LM32RegisterInfo.h
  29. +116 −0 lib/Target/LM32/LM32RegisterInfo.td
  30. +48 −0 lib/Target/LM32/LM32Relocations.h
  31. +44 −0 lib/Target/LM32/LM32Schedule.td
  32. +23 −0 lib/Target/LM32/LM32SelectionDAGInfo.cpp
  33. +31 −0 lib/Target/LM32/LM32SelectionDAGInfo.h
  34. +42 −0 lib/Target/LM32/LM32Subtarget.cpp
  35. +71 −0 lib/Target/LM32/LM32Subtarget.h
  36. +67 −0 lib/Target/LM32/LM32TargetMachine.cpp
  37. +85 −0 lib/Target/LM32/LM32TargetMachine.h
  38. +94 −0 lib/Target/LM32/LM32TargetObjectFile.cpp
  39. +40 −0 lib/Target/LM32/LM32TargetObjectFile.h
  40. 0 lib/Target/{Mico32 → LM32}/LM32_opcodes.ods
  41. +7 −0 lib/Target/LM32/MCTargetDesc/CMakeLists.txt
  42. +24 −0 lib/Target/LM32/MCTargetDesc/LLVMBuild.txt
  43. +69 −0 lib/Target/LM32/MCTargetDesc/LM32MCAsmInfo.cpp
  44. +31 −0 lib/Target/LM32/MCTargetDesc/LM32MCAsmInfo.h
  45. +99 −0 lib/Target/LM32/MCTargetDesc/LM32MCTargetDesc.cpp
  46. +41 −0 lib/Target/LM32/MCTargetDesc/LM32MCTargetDesc.h
  47. +17 −0 lib/Target/LM32/MCTargetDesc/Makefile
  48. +22 −0 lib/Target/LM32/Makefile
  49. +209 −0 lib/Target/LM32/README
  50. +8 −0 lib/Target/LM32/TargetInfo/CMakeLists.txt
  51. +24 −0 lib/Target/LM32/TargetInfo/LLVMBuild.txt
  52. +19 −0 lib/Target/LM32/TargetInfo/LM32TargetInfo.cpp
  53. +15 −0 lib/Target/LM32/TargetInfo/Makefile
  54. +0 −31 lib/Target/Mico32/CMakeLists.txt
  55. +0 −35 lib/Target/Mico32/LLVMBuild.txt
  56. +0 −7 lib/Target/Mico32/MCTargetDesc/CMakeLists.txt
  57. +0 −24 lib/Target/Mico32/MCTargetDesc/LLVMBuild.txt
  58. +0 −17 lib/Target/Mico32/MCTargetDesc/Makefile
  59. +0 −69 lib/Target/Mico32/MCTargetDesc/Mico32MCAsmInfo.cpp
  60. +0 −31 lib/Target/Mico32/MCTargetDesc/Mico32MCAsmInfo.h
  61. +0 −99 lib/Target/Mico32/MCTargetDesc/Mico32MCTargetDesc.cpp
  62. +0 −41 lib/Target/Mico32/MCTargetDesc/Mico32MCTargetDesc.h
  63. +0 −22 lib/Target/Mico32/Makefile
  64. +0 −40 lib/Target/Mico32/Mico32.h
  65. +0 −77 lib/Target/Mico32/Mico32.td
  66. +0 −223 lib/Target/Mico32/Mico32AsmPrinter.cpp
  67. +0 −50 lib/Target/Mico32/Mico32CallingConv.td
  68. +0 −117 lib/Target/Mico32/Mico32ELFWriterInfo.cpp
  69. +0 −58 lib/Target/Mico32/Mico32ELFWriterInfo.h
  70. +0 −410 lib/Target/Mico32/Mico32FrameLowering.cpp
  71. +0 −85 lib/Target/Mico32/Mico32FrameLowering.h
  72. +0 −278 lib/Target/Mico32/Mico32ISelDAGToDAG.cpp
  73. +0 −1,014 lib/Target/Mico32/Mico32ISelLowering.cpp
  74. +0 −194 lib/Target/Mico32/Mico32ISelLowering.h
  75. +0 −227 lib/Target/Mico32/Mico32InstrFormats.td
  76. +0 −374 lib/Target/Mico32/Mico32InstrInfo.cpp
  77. +0 −135 lib/Target/Mico32/Mico32InstrInfo.h
Sorry, we could not display the entire diff because too many files (1,143) changed.
View
2 CMakeLists.txt
@@ -75,7 +75,7 @@ set(LLVM_ALL_TARGETS
Hexagon
Mips
MBlaze
- Mico32
+ LM32
MSP430
PowerPC
PTX
View
2 autoconf/config.sub
@@ -262,7 +262,6 @@ case $basic_machine in
| ip2k | iq2000 \
| le32 | le64 \
| lm32 \
- | mico32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
@@ -375,7 +374,6 @@ case $basic_machine in
| ip2k-* | iq2000-* \
| le32-* | le64-* \
| lm32-* \
- | mico32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
View
12 autoconf/configure.ac
@@ -354,7 +354,7 @@ AC_CACHE_CHECK([target architecture],[llvm_cv_target_arch],
sparc*-*) llvm_cv_target_arch="Sparc" ;;
powerpc*-*) llvm_cv_target_arch="PowerPC" ;;
arm*-*) llvm_cv_target_arch="ARM" ;;
- mico32-*) llvm_cv_target_arch="Mico32" ;;
+ lm32-*) llvm_cv_target_arch="LM32" ;;
mips-*) llvm_cv_target_arch="Mips" ;;
xcore-*) llvm_cv_target_arch="XCore" ;;
msp430-*) llvm_cv_target_arch="MSP430" ;;
@@ -502,7 +502,7 @@ else
PowerPC) AC_SUBST(TARGET_HAS_JIT,1) ;;
x86_64) AC_SUBST(TARGET_HAS_JIT,1) ;;
ARM) AC_SUBST(TARGET_HAS_JIT,1) ;;
- Mico32) AC_SUBST(TARGET_HAS_JIT,0) ;;
+ LM32) AC_SUBST(TARGET_HAS_JIT,0) ;;
Mips) AC_SUBST(TARGET_HAS_JIT,1) ;;
XCore) AC_SUBST(TARGET_HAS_JIT,0) ;;
MSP430) AC_SUBST(TARGET_HAS_JIT,0) ;;
@@ -619,14 +619,14 @@ dnl Allow specific targets to be specified for building (or not)
TARGETS_TO_BUILD=""
AC_ARG_ENABLE([targets],AS_HELP_STRING([--enable-targets],
[Build specific host targets: all or target1,target2,... Valid targets are:
- host, x86, x86_64, sparc, powerpc, arm, mico32, mips, spu, hexagon,
+ host, x86, x86_64, sparc, powerpc, arm, lm32, mips, spu, hexagon,
xcore, msp430, ptx, cbe, and cpp (default=all)]),,
enableval=all)
if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
- all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mico32 Mips CellSPU XCore MSP430 CBackend CppBackend MBlaze PTX Hexagon" ;;
+ all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM LM32 Mips CellSPU XCore MSP430 CBackend CppBackend MBlaze PTX Hexagon" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@@ -634,7 +634,7 @@ case "$enableval" in
sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
- mico32) TARGETS_TO_BUILD="Mico32 $TARGETS_TO_BUILD" ;;
+ lm32) TARGETS_TO_BUILD="LM32 $TARGETS_TO_BUILD" ;;
mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
xcore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
@@ -650,7 +650,7 @@ case "$enableval" in
Sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
PowerPC) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
- Mico32) TARGETS_TO_BUILD="Mico32 $TARGETS_TO_BUILD" ;;
+ LM32) TARGETS_TO_BUILD="LM32 $TARGETS_TO_BUILD" ;;
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
View
10 configure
@@ -3880,7 +3880,7 @@ else
sparc*-*) llvm_cv_target_arch="Sparc" ;;
powerpc*-*) llvm_cv_target_arch="PowerPC" ;;
arm*-*) llvm_cv_target_arch="ARM" ;;
- mico32-*) llvm_cv_target_arch="Mico32" ;;
+ lm32-*) llvm_cv_target_arch="LM32" ;;
mips-*) llvm_cv_target_arch="Mips" ;;
xcore-*) llvm_cv_target_arch="XCore" ;;
msp430-*) llvm_cv_target_arch="MSP430" ;;
@@ -5099,7 +5099,7 @@ else
;;
ARM) TARGET_HAS_JIT=1
;;
- Mico32) TARGET_HAS_JIT=0
+ LM32) TARGET_HAS_JIT=0
;;
Mips) TARGET_HAS_JIT=1
;;
@@ -5297,7 +5297,7 @@ if test "$enableval" = host-only ; then
enableval=host
fi
case "$enableval" in
- all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM Mico32 Mips CellSPU XCore MSP430 CBackend CppBackend MBlaze PTX Hexagon" ;;
+ all) TARGETS_TO_BUILD="X86 Sparc PowerPC ARM LM32 Mips CellSPU XCore MSP430 CBackend CppBackend MBlaze PTX Hexagon" ;;
*)for a_target in `echo $enableval|sed -e 's/,/ /g' ` ; do
case "$a_target" in
x86) TARGETS_TO_BUILD="X86 $TARGETS_TO_BUILD" ;;
@@ -5305,7 +5305,7 @@ case "$enableval" in
sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
powerpc) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
arm) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
- mico32) TARGETS_TO_BUILD="Mico32 $TARGETS_TO_BUILD" ;;
+ lm32) TARGETS_TO_BUILD="LM32 $TARGETS_TO_BUILD" ;;
mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
spu) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
xcore) TARGETS_TO_BUILD="XCore $TARGETS_TO_BUILD" ;;
@@ -5321,7 +5321,7 @@ case "$enableval" in
Sparc) TARGETS_TO_BUILD="Sparc $TARGETS_TO_BUILD" ;;
PowerPC) TARGETS_TO_BUILD="PowerPC $TARGETS_TO_BUILD" ;;
ARM) TARGETS_TO_BUILD="ARM $TARGETS_TO_BUILD" ;;
- Mico32) TARGETS_TO_BUILD="Mico32 $TARGETS_TO_BUILD" ;;
+ LM32) TARGETS_TO_BUILD="LM32 $TARGETS_TO_BUILD" ;;
Mips) TARGETS_TO_BUILD="Mips $TARGETS_TO_BUILD" ;;
MBlaze) TARGETS_TO_BUILD="MBlaze $TARGETS_TO_BUILD" ;;
CellSPU|SPU) TARGETS_TO_BUILD="CellSPU $TARGETS_TO_BUILD" ;;
View
2 include/llvm/ADT/Triple.h
@@ -45,7 +45,7 @@ class Triple {
arm, // ARM; arm, armv.*, xscale
cellspu, // CellSPU: spu, cellspu
- mico32, // Mico32: mico32
+ lm32, // LM32: lm32
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel, psp
View
2 include/llvm/Support/ELF.h
@@ -239,7 +239,7 @@ enum {
EM_SCORE7 = 135, // Sunplus S+core7 RISC processor
EM_DSP24 = 136, // New Japan Radio (NJR) 24-bit DSP Processor
EM_VIDEOCORE3 = 137, // Broadcom VideoCore III processor
- EM_LATTICEMICO32 = 138, // RISC processor for Lattice FPGA architecture
+ EM_LM32 = 138, // RISC processor for Lattice FPGA architecture
EM_SE_C17 = 139, // Seiko Epson C17 family
EM_TI_C6000 = 140, // The Texas Instruments TMS320C6000 DSP family
EM_TI_C2000 = 141, // The Texas Instruments TMS320C2000 DSP family
View
12 lib/Support/Triple.cpp
@@ -20,7 +20,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case arm: return "arm";
case cellspu: return "cellspu";
- case mico32: return "mico32";
+ case lm32: return "lm32";
case hexagon: return "hexagon";
case mips: return "mips";
case mipsel: return "mipsel";
@@ -59,7 +59,7 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case ppc64:
case ppc: return "ppc";
- case mico32: return "mico32";
+ case lm32: return "lm32";
case mblaze: return "mblaze";
@@ -139,8 +139,8 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
return arm;
if (Name == "cellspu")
return cellspu;
- if (Name == "mico32")
- return mico32;
+ if (Name == "lm32")
+ return lm32;
if (Name == "mips")
return mips;
if (Name == "mipsel")
@@ -296,8 +296,8 @@ Triple::ArchType Triple::ParseArch(StringRef ArchName) {
return cellspu;
else if (ArchName == "msp430")
return msp430;
- else if (ArchName == "mico32")
- return mico32;
+ else if (ArchName == "lm32")
+ return lm32;
else if (ArchName == "mips" || ArchName == "mipseb" ||
ArchName == "mipsallegrex")
return mips;
View
2 lib/Target/LLVMBuild.txt
@@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;
[common]
-subdirectories = ARM CBackend CellSPU CppBackend Hexagon MBlaze Mico32 MSP430 Mips PTX PowerPC Sparc X86 XCore
+subdirectories = ARM CBackend CellSPU CppBackend Hexagon MBlaze LM32 MSP430 Mips PTX PowerPC Sparc X86 XCore
; This is a special group whose required libraries are extended (by llvm-build)
; with the best execution engine (the native JIT, if available, or the
View
31 lib/Target/LM32/CMakeLists.txt
@@ -0,0 +1,31 @@
+set(LLVM_TARGET_DEFINITIONS LM32.td)
+
+tablegen(LLVM LM32GenRegisterInfo.inc -gen-register-info)
+tablegen(LLVM LM32GenInstrInfo.inc -gen-instr-info)
+tablegen(LLVM LM32GenCodeEmitter.inc -gen-emitter)
+tablegen(LLVM LM32GenAsmWriter.inc -gen-asm-writer)
+tablegen(LLVM LM32GenAsmMatcher.inc -gen-asm-matcher)
+tablegen(LLVM LM32GenDAGISel.inc -gen-dag-isel)
+tablegen(LLVM LM32GenCallingConv.inc -gen-callingconv)
+tablegen(LLVM LM32GenSubtargetInfo.inc -gen-subtarget)
+tablegen(LLVM LM32GenIntrinsics.inc -gen-tgt-intrinsic)
+tablegen(LLVM LM32GenEDInfo.inc -gen-enhanced-disassembly-info)
+add_public_tablegen_target(LM32CommonTableGen)
+
+add_llvm_target(LM32CodeGen
+ LM32AsmPrinter.cpp
+ LM32ELFWriterInfo.cpp
+ LM32FrameLowering.cpp
+ LM32InstrInfo.cpp
+ LM32ISelDAGToDAG.cpp
+ LM32ISelLowering.cpp
+ LM32RegisterInfo.cpp
+ LM32SelectionDAGInfo.cpp
+ LM32Subtarget.cpp
+ LM32TargetMachine.cpp
+ LM32TargetObjectFile.cpp
+ )
+
+add_subdirectory(TargetInfo)
+add_subdirectory(MCTargetDesc)
+
View
35 lib/Target/LM32/LLVMBuild.txt
@@ -0,0 +1,35 @@
+;===- ./lib/Target/LM32/LLVMBuild.txt --------------------------*- Conf -*--===;
+;
+; The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+; http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[common]
+subdirectories = MCTargetDesc TargetInfo
+
+[component_0]
+type = TargetGroup
+name = LM32
+parent = Target
+has_asmparser = 1
+has_asmprinter = 1
+has_disassembler = 1
+
+[component_1]
+type = Library
+name = LM32CodeGen
+parent = LM32
+required_libraries = CodeGen Core LM32Desc LM32Info MC SelectionDAG Support Target
+add_to_library_groups = LM32
+
View
40 lib/Target/LM32/LM32.h
@@ -0,0 +1,40 @@
+//===-- LM32.h - Top-level interface for LM32 -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the entry points for global functions defined in
+// the LLVM LM32 back-end.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TARGET_LM32_H
+#define TARGET_LM32_H
+
+#include "MCTargetDesc/LM32MCTargetDesc.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+ class LM32TargetMachine;
+ class FunctionPass;
+ class MachineCodeEmitter;
+ class MCCodeEmitter;
+ //class TargetAsmBackend;
+ class formatted_raw_ostream;
+
+ MCCodeEmitter *createLM32MCCodeEmitter(const Target &,
+ TargetMachine &TM,
+ MCContext &Ctx);
+
+ //TargetAsmBackend *createLM32AsmBackend(const Target &, const std::string &);
+
+ FunctionPass *createLM32ISelDag(LM32TargetMachine &TM);
+
+ extern Target TheLM32Target;
+} // end namespace llvm;
+
+#endif
View
77 lib/Target/LM32/LM32.td
@@ -0,0 +1,77 @@
+//===- LM32.td - Describe the LM32 Target Machine -------------*- tblgen -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// This is the top level entry point for the LM32 target.
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Target-independent interfaces
+//===----------------------------------------------------------------------===//
+
+include "llvm/Target/Target.td"
+
+//===----------------------------------------------------------------------===//
+// Register File, Calling Conv, Instruction Descriptions
+//===----------------------------------------------------------------------===//
+
+include "LM32RegisterInfo.td"
+include "LM32Schedule.td"
+include "LM32InstrInfo.td"
+include "LM32CallingConv.td"
+
+def LM32InstrInfo : InstrInfo;
+
+//===----------------------------------------------------------------------===//
+// Subtarget Features.
+//===----------------------------------------------------------------------===//
+//FIXME: added for the (currently) undocumented DIV/MOD instructions
+def FeatureSDIV :
+ SubtargetFeature<"sdiv", "HasSDIV", "false",
+ "enable undocumented div 0x27 and mod 0x35 instructions - currently does nothing">;
+
+def FeatureDIV :
+ SubtargetFeature<"div", "HasDIV", "true",
+ "enable divu and modu instructions.">;
+
+def FeatureMUL :
+ SubtargetFeature<"mul", "HasMUL", "true",
+ "enable mul and muli instructions.">;
+
+def FeatureBarrel :
+ SubtargetFeature<"barrel", "HasBarrel", "true",
+ "Enable barrel shifter instructions">;
+
+def FeatureSPBias :
+ SubtargetFeature<"nospbias", "HasSPBias", "false",
+ "SP points to last used 32 bit word on stack (not ABI compilant)">;
+
+//===----------------------------------------------------------------------===//
+// LM32 supported processors.
+//===----------------------------------------------------------------------===//
+
+def : Processor< "lm32", LM32Itineraries, []>;
+
+
+//===----------------------------------------------------------------------===//
+// Use an MC assembly printer
+//===----------------------------------------------------------------------===//
+
+//def LM32AsmWriter : AsmWriter {
+// string AsmWriterClassName = "InstPrinter";
+// bit isMCAsmWriter = 1;
+//}
+
+//===----------------------------------------------------------------------===//
+// Target Declaration
+//===----------------------------------------------------------------------===//
+
+def LM32 : Target {
+ let InstructionSet = LM32InstrInfo;
+// let AssemblyWriters = [LM32AsmWriter];
+}
+
View
223 lib/Target/LM32/LM32AsmPrinter.cpp
@@ -0,0 +1,223 @@
+//===-- LM32AsmPrinter.cpp - LM32 LLVM assembly writer --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a printer that converts from our internal representation
+// of machine-dependent LLVM code to GAS-format LM32 assembly language.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "asm-printer"
+#include "LM32.h"
+#include "LM32InstrInfo.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+namespace {
+ class LM32AsmPrinter : public AsmPrinter {
+ public:
+ LM32AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+ : AsmPrinter(TM, Streamer) {}
+
+ virtual const char *getPassName() const {
+ return "LM32 Assembly Printer";
+ }
+
+ // The printXXXOperand functions are referenced in the
+ // LM32InstrInfo.td file.
+ void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printUnsignedImm(const MachineInstr *MI, int opNum, raw_ostream &O);
+ void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
+ const char *Modifier = 0);
+
+ /// printInstruction - This method is automatically generated by tblgen
+ void printInstruction(const MachineInstr *MI, raw_ostream &O);
+
+ /// getRegisterName - This method is automatically generated by tblgen
+ static const char *getRegisterName(unsigned RegNo);
+
+ void EmitInstruction(const MachineInstr *MI) {
+ SmallString<128> Str;
+ raw_svector_ostream OS(Str);
+ printInstruction(MI, OS);
+ OutStreamer.EmitRawText(OS.str());
+ }
+ bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
+ bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O);
+ void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
+ void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
+ void printS16ImmOperand(const MachineInstr *MI,
+ unsigned OpNo, raw_ostream &O);
+ };
+} // end of anonymous namespace
+
+#include "LM32GenAsmWriter.inc"
+
+extern "C" void LLVMInitializeLM32AsmPrinter() {
+ RegisterAsmPrinter<LM32AsmPrinter> X(TheLM32Target);
+}
+
+void LM32AsmPrinter::printUnsignedImm(const MachineInstr *MI, int opNum,
+ raw_ostream &O)
+{
+ const MachineOperand &MO = MI->getOperand(opNum);
+ if (MO.isImm())
+ O << (uint32_t)MO.getImm();
+ else
+ printOperand(MI, opNum, O);
+}
+
+// Used for ADDRri addressing mode.
+// This will get passed a register and offset.
+// Modifiers are specified in the XXXInstrInfo.td file. E.g. declaring
+// the instruction as
+// <..."add ${addr:arith}, $dst", [(set IntRegs:$dst, ADDRri:$addr)..>;
+// will cause TableGen to pass the modifier "arith" to printMemOperand.
+// See SPARC for example.
+void LM32AsmPrinter::
+printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O,
+ const char *Modifier)
+{
+ O << "(";
+ printOperand(MI, opNum, O);
+ O << "+";
+ printOperand(MI, opNum+1, O);
+ O << ")";
+}
+
+
+void LM32AsmPrinter::
+printOperand(const MachineInstr *MI, int opNum, raw_ostream &O)
+{
+ const MachineOperand &MO = MI->getOperand(opNum);
+ switch (MO.getType()) {
+ case MachineOperand::MO_Register:
+ assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
+ "Virtual registers should be already mapped!");
+ O << getRegisterName(MO.getReg());
+ break;
+
+ case MachineOperand::MO_Immediate:
+ O << MO.getImm();
+ break;
+ case MachineOperand::MO_MachineBasicBlock:
+ O << *MO.getMBB()->getSymbol();
+ return;
+ case MachineOperand::MO_GlobalAddress:
+ O << *Mang->getSymbol(MO.getGlobal());
+ printOffset(MO.getOffset(), O);
+ break;
+ case MachineOperand::MO_ExternalSymbol:
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
+ break;
+ case MachineOperand::MO_ConstantPoolIndex:
+ O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
+ << MO.getIndex();
+ break;
+ case MachineOperand::MO_JumpTableIndex:
+ O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+ << '_' << MO.getIndex();
+ break;
+ default:
+ llvm_unreachable("<unknown operand type>");
+ break;
+ }
+}
+
+void LM32AsmPrinter::
+printS16ImmOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
+{
+ O << (short) MI->getOperand(OpNo).getImm();
+}
+
+
+
+/// PrintAsmOperand - Print out an operand for an inline asm expression.
+///
+bool LM32AsmPrinter::
+PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant,
+ const char *ExtraCode, raw_ostream &O)
+{
+ if (ExtraCode && ExtraCode[0]) {
+ if (ExtraCode[1] != 0) return true; // Unknown modifier.
+
+ switch (ExtraCode[0]) {
+ default: return true; // Unknown modifier.
+ case 'r':
+ break;
+ }
+ }
+
+ printOperand(MI, OpNo, O);
+
+ return false;
+}
+
+bool LM32AsmPrinter::
+PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O)
+{
+ if (ExtraCode && ExtraCode[0])
+ return true; // Unknown modifier
+
+ O << '[';
+ printOperand(MI, OpNo, O);
+ O << ']';
+
+ return false;
+}
+
+void LM32AsmPrinter::
+printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
+{
+ if (MI->getOperand(OpNo).isImm()) {
+ assert(0 && "Only symbols should be getting to this point");
+ printS16ImmOperand(MI, OpNo, O);
+ } else {
+ O << "hi(";
+ printOperand(MI, OpNo, O);
+ O << ")";
+ }
+}
+
+void LM32AsmPrinter::
+printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O)
+{
+ if (MI->getOperand(OpNo).isImm()) {
+ assert(0 && "Only symbols should be getting to this point");
+ printS16ImmOperand(MI, OpNo, O);
+ } else {
+ O << "lo(";
+ printOperand(MI, OpNo, O);
+ O << ")";
+ }
+}
+
View
50 lib/Target/LM32/LM32CallingConv.td
@@ -0,0 +1,50 @@
+//===-- LM32CallingConv.td - Calling Conventions for LM32 -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This describes the calling conventions for the LM32 architecture.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// LM32 Calling Conventions
+//===----------------------------------------------------------------------===//
+
+// Note it looks like LLVM supports passing or return stucture arguments
+// directly in registers.
+// http://nondot.org/sabre/LLVMNotes/
+// from the description of this feature at:
+// http://nondot.org/sabre/LLVMNotes/FirstClassAggregates.txt
+// it sounds like this should "just work".... we'll see.
+// See also: http://nondot.org/sabre/LLVMNotes/CustomCallingConventions.txt
+
+
+def CC_LM32 : CallingConv<[
+ // Promote i8/i16 arguments to i32.
+ CCIfType<[i8, i16], CCPromoteToType<i32>>,
+
+ // Integer and float arguments are passed in integer registers.
+ CCIfType<[i32, f32], CCAssignToReg<[R1, R2, R3, R4, R5, R6, R7, R8]>>,
+
+ // Integer values and floats get stored in stack slots that are 4 bytes in
+ // size and 4-byte aligned.
+ CCIfType<[i32, f32], CCAssignToStack<4, 4>>
+
+]>;
+
+// Structure returns "sret" are done by the compiler and labeled as such
+// in LLVM IR. Unsupported types should get handled as structures. Target
+// dependent codegen should not have to do anything special to handle sret.
+
+// Note the return registers (and caller saves) should
+// be "Defs" in the call instruction in LM32InstrInfo.td.
+def RetCC_LM32 : CallingConv<[
+ // i32 and f32 are returned in registers R1, R2.
+ CCIfType<[i32, f32], CCAssignToReg<[R1, R2]>>
+]>;
+
View
117 lib/Target/LM32/LM32ELFWriterInfo.cpp
@@ -0,0 +1,117 @@
+//===-- LM32ELFWriterInfo.cpp - ELF Writer Info for the LM32 backend --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements ELF writer information for the LM32 backend.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LM32ELFWriterInfo.h"
+#include "LM32Relocations.h"
+#include "llvm/Function.h"
+#include "llvm/Support/ELF.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetMachine.h"
+
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Implementation of the LM32ELFWriterInfo class
+//===----------------------------------------------------------------------===//
+
+LM32ELFWriterInfo::LM32ELFWriterInfo(TargetMachine &TM)
+ : TargetELFWriterInfo(TM.getTargetData()->getPointerSizeInBits() == 64,
+ TM.getTargetData()->isLittleEndian()) {
+}
+
+LM32ELFWriterInfo::~LM32ELFWriterInfo() {}
+
+unsigned LM32ELFWriterInfo::getRelocationType(unsigned MachineRelTy) const {
+llvm_unreachable("unknown lm32 relocation type");
+ switch (MachineRelTy) {
+ case LM32::reloc_pcrel_word:
+ return ELF::R_MICROBLAZE_64_PCREL;
+ case LM32::reloc_absolute_word:
+ return ELF::R_MICROBLAZE_NONE;
+ default:
+ llvm_unreachable("unknown lm32 machine relocation type");
+ }
+ return 0;
+}
+
+long int LM32ELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy,
+ long int Modifier) const {
+llvm_unreachable("unknown lm32 relocation type");
+ switch (RelTy) {
+ case ELF::R_MICROBLAZE_32_PCREL:
+ return Modifier - 4;
+ case ELF::R_MICROBLAZE_32:
+ return Modifier;
+ default:
+ llvm_unreachable("unknown lm32 relocation type");
+ }
+ return 0;
+}
+
+unsigned LM32ELFWriterInfo::getRelocationTySize(unsigned RelTy) const {
+llvm_unreachable("unknown lm32 relocation type");
+ // FIXME: Most of these sizes are guesses based on the name
+ switch (RelTy) {
+ case ELF::R_MICROBLAZE_32:
+ case ELF::R_MICROBLAZE_32_PCREL:
+ case ELF::R_MICROBLAZE_32_PCREL_LO:
+ case ELF::R_MICROBLAZE_32_LO:
+ case ELF::R_MICROBLAZE_SRO32:
+ case ELF::R_MICROBLAZE_SRW32:
+ case ELF::R_MICROBLAZE_32_SYM_OP_SYM:
+ case ELF::R_MICROBLAZE_GOTOFF_32:
+ return 32;
+
+ case ELF::R_MICROBLAZE_64_PCREL:
+ case ELF::R_MICROBLAZE_64:
+ case ELF::R_MICROBLAZE_GOTPC_64:
+ case ELF::R_MICROBLAZE_GOT_64:
+ case ELF::R_MICROBLAZE_PLT_64:
+ case ELF::R_MICROBLAZE_GOTOFF_64:
+ return 64;
+ }
+
+ return 0;
+}
+
+bool LM32ELFWriterInfo::isPCRelativeRel(unsigned RelTy) const {
+llvm_unreachable("unknown lm32 relocation type");
+ // FIXME: Most of these are guesses based on the name
+ switch (RelTy) {
+ case ELF::R_MICROBLAZE_32_PCREL:
+ case ELF::R_MICROBLAZE_64_PCREL:
+ case ELF::R_MICROBLAZE_32_PCREL_LO:
+ case ELF::R_MICROBLAZE_GOTPC_64:
+ return true;
+ }
+
+ return false;
+}
+
+unsigned LM32ELFWriterInfo::getAbsoluteLabelMachineRelTy() const {
+llvm_unreachable("unknown lm32 relocation type");
+ return LM32::reloc_absolute_word;
+}
+
+long int LM32ELFWriterInfo::computeRelocation(unsigned SymOffset,
+ unsigned RelOffset,
+ unsigned RelTy) const {
+llvm_unreachable("unknown lm32 relocation type");
+ if (RelTy == ELF::R_MICROBLAZE_32_PCREL || ELF::R_MICROBLAZE_64_PCREL)
+ return SymOffset - (RelOffset + 4);
+ else
+ assert("computeRelocation unknown for this relocation type");
+
+ return 0;
+}
View
58 lib/Target/LM32/LM32ELFWriterInfo.h
@@ -0,0 +1,58 @@
+//===-- LM32ELFWriterInfo.h - ELF Writer Info for LM32 ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements ELF writer information for the LM32 backend.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LM32_ELF_WRITER_INFO_H
+#define LM32_ELF_WRITER_INFO_H
+
+#include "llvm/Target/TargetELFWriterInfo.h"
+
+namespace llvm {
+
+ class LM32ELFWriterInfo : public TargetELFWriterInfo {
+ public:
+ LM32ELFWriterInfo(TargetMachine &TM);
+ virtual ~LM32ELFWriterInfo();
+
+ /// getRelocationType - Returns the target specific ELF Relocation type.
+ /// 'MachineRelTy' contains the object code independent relocation type
+ virtual unsigned getRelocationType(unsigned MachineRelTy) const;
+
+ /// hasRelocationAddend - True if the target uses an addend in the
+ /// ELF relocation entry.
+ virtual bool hasRelocationAddend() const { return false; }
+
+ /// getDefaultAddendForRelTy - Gets the default addend value for a
+ /// relocation entry based on the target ELF relocation type.
+ virtual long int getDefaultAddendForRelTy(unsigned RelTy,
+ long int Modifier = 0) const;
+
+ /// getRelTySize - Returns the size of relocatable field in bits
+ virtual unsigned getRelocationTySize(unsigned RelTy) const;
+
+ /// isPCRelativeRel - True if the relocation type is pc relative
+ virtual bool isPCRelativeRel(unsigned RelTy) const;
+
+ /// getJumpTableRelocationTy - Returns the machine relocation type used
+ /// to reference a jumptable.
+ virtual unsigned getAbsoluteLabelMachineRelTy() const;
+
+ /// computeRelocation - Some relocatable fields could be relocated
+ /// directly, avoiding the relocation symbol emission, compute the
+ /// final relocation value for this symbol.
+ virtual long int computeRelocation(unsigned SymOffset, unsigned RelOffset,
+ unsigned RelTy) const;
+ };
+
+} // end llvm namespace
+
+#endif // LM32_ELF_WRITER_INFO_H
View
410 lib/Target/LM32/LM32FrameLowering.cpp
@@ -0,0 +1,410 @@
+//=====- LM32FrameLowering.cpp - LM32 Frame Information ---------- C++ -*-====//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the LM32 implementation of TargetFrameLowering class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LM32.h"
+#include "LM32FrameLowering.h"
+#include "LM32InstrInfo.h"
+#include "LM32MachineFunctionInfo.h"
+#include "llvm/Function.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/RegisterScavenging.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "LM32Subtarget.h"
+
+
+using namespace llvm;
+
+LM32FrameLowering::LM32FrameLowering(const LM32Subtarget &subtarget)
+ : TargetFrameLowering(TargetFrameLowering::StackGrowsDown,
+ 4 /*StackAlignment*/,
+ 0 /*LocalAreaOffset*/,
+ 4 /*TransientStackAlignment*/),
+ Subtarget(subtarget) {
+ // Do nothing
+}
+
+
+/// determineFrameLayout - Align the frame and maximum call frame and
+/// updated the sizes. Copied from SPU.
+void LM32FrameLowering::
+determineFrameLayout(MachineFunction &MF) const {
+ MachineFrameInfo *MFI = MF.getFrameInfo();
+
+ // Get the number of bytes to allocate from the FrameInfo
+ unsigned FrameSize = MFI->getStackSize();
+
+ // Get the alignments provided by the target, and the maximum alignment
+ // (if any) of the fixed frame objects.
+ unsigned TargetAlign = getStackAlignment();
+ unsigned Align = std::max(TargetAlign, MFI->getMaxAlignment());
+ assert(isPowerOf2_32(Align) && "Alignment is not power of 2");
+ unsigned AlignMask = Align - 1;
+
+ // Get the maximum call frame size of all the calls.
+ unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
+
+ // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
+ // that allocations will be aligned.
+ if (MFI->hasVarSizedObjects())
+ maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask;
+
+ // Update maximum call frame size.
+ MFI->setMaxCallFrameSize(maxCallFrameSize);
+
+ // Include call frame size in total.
+ FrameSize += maxCallFrameSize;
+
+ // Make sure the frame is aligned.
+ FrameSize = (FrameSize + AlignMask) & ~AlignMask;
+
+ // Update frame info.
+ MFI->setStackSize(FrameSize);
+}
+
+/// hasFP - Return true if the specified function should have a dedicated frame
+/// pointer register. This is true if the stacksize > 0 and either the
+/// function has variable sized allocas or frame pointer elimination
+/// is disabled or stack alignment is less than requested alignment.
+///
+bool LM32FrameLowering::
+hasFP(const MachineFunction &MF) const {
+ const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
+ const MachineFrameInfo *MFI = MF.getFrameInfo();
+
+ return (MF.getTarget().Options.DisableFramePointerElim(MF) ||
+ RegInfo->needsStackRealignment(MF) ||
+ MF.getFrameInfo()->hasVarSizedObjects() ||
+ MFI->isFrameAddressTaken());
+}
+
+
+// Generate the function prologue.
+// This is based on XCore with some SPU influence.
+void LM32FrameLowering::
+emitPrologue(MachineFunction &MF) const {
+ MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
+ MachineBasicBlock::iterator MBBI = MBB.begin();
+ MachineFrameInfo *MFrmInf = MF.getFrameInfo();
+ MachineModuleInfo *MMI = &MF.getMMI();
+
+ LM32FunctionInfo *MFuncInf = MF.getInfo<LM32FunctionInfo>();
+ const LM32InstrInfo &TII =
+ *static_cast<const LM32InstrInfo*>(MF.getTarget().getInstrInfo());
+
+ DebugLoc dl = (MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc());
+
+ // determineFrameLayout() sets some stack related sizes so do it first.
+ determineFrameLayout(MF);
+
+ // Check the maximum call frame size of all the calls is sensible.
+ assert(MFrmInf->getMaxCallFrameSize()%4 == 0 && "Misaligned call frame size");
+
+ bool FP = hasFP(MF);
+ bool needsRealignment =
+ MF.getTarget().getRegisterInfo()->needsStackRealignment(MF);
+
+
+ // Get the frame size.
+ int FrameSize = MFrmInf->getStackSize();
+ assert(FrameSize%4 == 0 &&
+ "LM32FrameLowering::emitPrologue Misaligned frame size");
+
+
+ bool emitFrameMoves = MMI->hasDebugInfo() ||
+ MF.getFunction()->needsUnwindTableEntry();
+
+ assert(((MFuncInf->getUsesLR() && FrameSize) || !MFuncInf->getUsesLR()) &&
+ "we should have a frame if LR is used.");
+ assert(((FP && FrameSize) || !FP) && "we should have a frame if FP is used.");
+
+ // Do we need to allocate space on the stack?
+ if (FrameSize) {
+ // adjust the stack pointer: RSP -= FrameSize
+ // Note we can only add 32767 offset in emitEpilogue()
+ // so we don't use 32768. See SPU for model of how to implement larger
+ // stack frames.
+ if (FrameSize < 32768) {
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::ADDI),
+ LM32::RSP).addReg(LM32::RSP).addImm(-FrameSize);
+ } else {
+ // We could use multiple instructions to generate the offset.
+ report_fatal_error("Unhandled frame size in function: " + MBB.getParent()->getFunction()->getName() + " size: " + Twine(FrameSize));
+ }
+
+ // Add the "machine moves" for the instructions we generated above, but in
+ // reverse order.
+ // Mapping for machine moves (see MCDwarf.cpp):
+ if (emitFrameMoves) {
+ std::vector<MachineMove> &Moves = MMI->getFrameMoves();
+
+ // Show update of SP.
+ MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::PROLOG_LABEL)).addSym(FrameLabel);
+
+ DEBUG(dbgs() << "\nFunction: "
+ << MF.getFunction()->getName() << " SP Frame debug location\n");
+ DEBUG(dbgs() << "Moving VirtFP: \n");
+ DEBUG(dbgs() << "VirtualFP = VirtFP[" << FrameSize << "]\n");
+ // Generate DW_CFA_def_cfa_offset for SP.
+ MachineLocation SPDst(MachineLocation::VirtualFP);
+ MachineLocation SPSrc(MachineLocation::VirtualFP, FrameSize);
+ Moves.push_back(MachineMove(FrameLabel, SPDst, SPSrc));
+ }
+
+ if (MFuncInf->getUsesLR()) {
+ // Save the LR (RRA) to the preallocated stack slot.
+ int LRSpillOffset = MFrmInf->getObjectOffset(MFuncInf->getLRSpillSlot())
+ +FrameSize;
+ LRSpillOffset += Subtarget.hasSPBias()? 4 : 0;
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::SW))
+ .addReg(LM32::RRA).addReg(LM32::RSP).addImm(LRSpillOffset);
+ MBB.addLiveIn(LM32::RRA);
+
+ if (emitFrameMoves) {
+ MCSymbol *SaveLRLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::PROLOG_LABEL))
+ .addSym(SaveLRLabel);
+ DEBUG(dbgs() << "\nFunction: "
+ << MF.getFunction()->getName() << " LR Frame debug location\n");
+ DEBUG(dbgs() << "Moving %RRA (link register): \n");
+ DEBUG(dbgs() << "VirtualFP[FPSpillOffset] = VirtFP[" << LRSpillOffset << "]\n");
+ MachineLocation CSDst(MachineLocation::VirtualFP, LRSpillOffset);
+ MachineLocation CSSrc(LM32::RRA);
+ MMI->getFrameMoves().push_back(MachineMove(SaveLRLabel, CSDst, CSSrc));
+ }
+ }
+
+ if (FP) {
+ // Save FP (R27) to the stack.
+ int FPSpillOffset =
+ MFrmInf->getObjectOffset(MFuncInf->getFPSpillSlot())+FrameSize;
+ FPSpillOffset += Subtarget.hasSPBias()? 4 : 0;
+
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::SW))
+ .addReg(LM32::RFP).addReg(LM32::RSP).addImm(FPSpillOffset);
+
+ // RFP is live-in. It is killed at the spill.
+ MBB.addLiveIn(LM32::RFP);
+ if (emitFrameMoves) {
+ DEBUG(dbgs() << "\nFunction: "
+ << MF.getFunction()->getName() << " FP Frame debug location\n");
+ DEBUG(dbgs() << "Moving FPreg: : "
+ << ((FP) ? "FP" : "SP") << " to \n");
+ DEBUG(dbgs() << "VirtualFP[FPSpillOffset] = VirtFP[" << FPSpillOffset << "]\n");
+ MCSymbol *SaveRFPLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::PROLOG_LABEL))
+ .addSym(SaveRFPLabel);
+ MachineLocation CSDst(MachineLocation::VirtualFP, FPSpillOffset);
+ MachineLocation CSSrc(LM32::RFP);
+ MMI->getFrameMoves().push_back(MachineMove(SaveRFPLabel, CSDst, CSSrc));
+ }
+ // Set the FP from the SP.
+ unsigned FramePtr = LM32::RFP;
+ // The FP points to the beginning of the frame ( = SP on entry),
+ // hence we add in the FrameSize.
+ FrameSize += Subtarget.hasSPBias()? 4 : 0;
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::ADDI),FramePtr)
+ .addReg(LM32::RSP).addImm(FrameSize);
+ if (emitFrameMoves) {
+ DEBUG(dbgs() << "FRAMEMOVE: FPreg: is now FP \n");
+ // Show FP is now valid.
+ MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl,TII.get(LM32::PROLOG_LABEL)).addSym(FrameLabel);
+ MachineLocation SPDst(FramePtr);
+ MachineLocation SPSrc(MachineLocation::VirtualFP);
+ MMI->getFrameMoves().push_back(MachineMove(FrameLabel, SPDst, SPSrc));
+ }
+ }
+ }
+
+#if 0
+ // from XCore (I believe):
+ if (emitFrameMoves) {
+ // Frame moves for callee saved.
+ std::vector<MachineMove> &Moves = MMI->getFrameMoves();
+ std::vector<std::pair<MCSymbol*, CalleeSavedInfo> >&SpillLabels =
+ MFuncInf->getSpillLabels();
+ for (unsigned I = 0, E = SpillLabels.size(); I != E; ++I) {
+ MCSymbol *SpillLabel = SpillLabels[I].first;
+ CalleeSavedInfo &CSI = SpillLabels[I].second;
+ int Offset = MFrmInf->getObjectOffset(CSI.getFrameIdx());
+ unsigned Reg = CSI.getReg();
+ MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
+ MachineLocation CSSrc(Reg);
+ Moves.push_back(MachineMove(SpillLabel, CSDst, CSSrc));
+ }
+ }
+#endif
+ // This is from PPC:
+ if (emitFrameMoves) {
+ MCSymbol *FrameLabel = MMI->getContext().CreateTempSymbol();
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::PROLOG_LABEL)).addSym(FrameLabel);
+ MCSymbol *ReadyLabel = 0;
+
+ MCSymbol *Label = FP ? ReadyLabel : FrameLabel;
+ int bias = 0;
+ if (!FP && Subtarget.hasSPBias())
+ bias = 4;
+
+ // Add callee saved registers to move list.
+ const std::vector<CalleeSavedInfo> &CSI = MFrmInf->getCalleeSavedInfo();
+ for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
+ int FrameIndex = CSI[I].getFrameIdx();
+ int Offset = MFrmInf->getObjectOffset(CSI[I].getFrameIdx());
+ unsigned Reg = CSI[I].getReg();
+ DEBUG(dbgs() << "\nFunction : "
+ << MF.getFunction()->getName() << " FRAME MOVES\n");
+ DEBUG(dbgs() << "<--------->\n");
+ DEBUG(dbgs() << "FPreg : "
+ << ((FP) ? "FP" : "SP") << "\n");
+ DEBUG(dbgs() << "Moving reg : " << Reg << "\n");
+ DEBUG(dbgs() << "FrameIndex : " << FrameIndex << "\n");
+ DEBUG(dbgs() << "FrameOffset : " << Offset << "\n");
+ DEBUG(dbgs() << "bias : " << bias << "\n");
+ Offset += bias;
+ //if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue;
+ MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
+ MachineLocation CSSrc(Reg);
+ MMI->getFrameMoves().push_back(MachineMove(Label, CSDst, CSSrc));
+ }
+ }
+
+}
+
+
+void LM32FrameLowering::
+emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
+ MachineFrameInfo *MFrmInf = MF.getFrameInfo();
+ MachineBasicBlock::iterator MBBI = prior(MBB.end());
+ const LM32InstrInfo &TII =
+ *static_cast<const LM32InstrInfo*>(MF.getTarget().getInstrInfo());
+ LM32FunctionInfo *MFuncInf = MF.getInfo<LM32FunctionInfo>();
+ assert(MBBI->getOpcode() == LM32::RET &&
+ "Can only put epilog before 'ret' instruction!");
+ DebugLoc dl = MBBI->getDebugLoc();
+
+ bool FP = hasFP(MF);
+
+ // Get the number of bytes allocated from the FrameInfo
+ int FrameSize = MFrmInf->getStackSize();
+
+ if (FrameSize) {
+ if (FP) {
+ // Restore FP (R27) from the stack.
+ int FPSpillOffset =
+ MFrmInf->getObjectOffset(MFuncInf->getFPSpillSlot())+FrameSize;
+ FPSpillOffset += Subtarget.hasSPBias()? 4 : 0;
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::LW))
+ .addReg(LM32::RFP).addReg(LM32::RSP).addImm(FPSpillOffset);
+ }
+
+ if (MFuncInf->getUsesLR()) {
+ // Restore the LR (RRA) from the preallocated stack slot.
+ int LRSpillOffset = MFrmInf->getObjectOffset(MFuncInf->getLRSpillSlot())
+ +FrameSize;
+ LRSpillOffset += Subtarget.hasSPBias()? 4 : 0;
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::LW))
+ .addReg(LM32::RRA).addReg(LM32::RSP).addImm(LRSpillOffset);
+ }
+
+ // SP += MFrmInf->getStackSize()
+ if (FrameSize < 32768) {
+ BuildMI(MBB, MBBI, dl, TII.get(LM32::ADDI), LM32::RSP)
+ .addReg(LM32::RSP).addImm(FrameSize);
+ } else {
+ assert( 0 && "Unimplemented - per function stack size limited to 32767 bytes.");
+ }
+ }
+}
+
+
+/// processFunctionBeforeFrameFinalized - This method is called immediately
+/// before the specified functions frame layout (MF.getFrameInfo()) is
+/// finalized. Once the frame is finalized, MO_FrameIndex operands are
+/// replaced with direct constants. This method is optional.
+void LM32FrameLowering::
+processFunctionBeforeFrameFinalized(MachineFunction &MF) const {}
+
+/// processFunctionBeforeCalleeSavedScan - This method is called immediately
+/// before PrologEpilogInserter scans the physical registers used to determine
+/// what callee saved registers should be spilled. This method is optional.
+/// ARM provides a complex example of this function.
+/// The following is based on XCore
+void LM32FrameLowering::
+processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ RegScavenger *RS) const {
+ MachineFrameInfo *MFrmInf = MF.getFrameInfo();
+ const TargetRegisterInfo *RegInfo = MF.getTarget().getRegisterInfo();
+ const TargetRegisterClass *RC = LM32::GPRRegisterClass;
+ LM32FunctionInfo *MFuncInf = MF.getInfo<LM32FunctionInfo>();
+ const bool LRUsed = MF.getRegInfo().isPhysRegUsed(LM32::RRA);
+ const bool hasFP = MF.getTarget().getFrameLowering()->hasFP(MF);
+ const bool isVarArg = MF.getFunction()->isVarArg();
+
+ // CreateFixedObject allocates space relative to the SP on entry to
+ // the function. Since SP(0) is occupied by incoming arguments (or
+ // whatever) we need to allocate the next slot on the stack (e.g. -4).
+ int offset = -4;
+
+ // For variadic functions we copy the parameters passed in registers
+ // onto the stack in the first positions in the frame. Therefore
+ // we don't fix the location of the LR and FP here, The ABI doesn't
+ // specify where they should be anyways.
+
+ // LR can be optimized out prior to now:
+ int FrameIdx;
+ if (LRUsed) {
+ MF.getRegInfo().setPhysRegUnused(LM32::RRA);
+
+ if ( !isVarArg )
+ FrameIdx = MFrmInf->CreateFixedObject(RC->getSize(), offset, true);
+ else
+ //FIXME: I'm lazy and didn't bother to assign the actual location.
+ FrameIdx = MFrmInf->CreateStackObject(RC->getSize(),
+ RC->getAlignment(), false);
+ offset -= 4;
+ MFuncInf->setUsesLR(FrameIdx);
+ MFuncInf->setLRSpillSlot(FrameIdx);
+ }
+
+ if (RegInfo->requiresRegisterScavenging(MF)) {
+ assert(0 && "Test register scavenging.");
+ // Reserve a slot close to SP or frame pointer.
+ RS->setScavengingFrameIndex(MFrmInf->CreateStackObject(RC->getSize(),
+ RC->getAlignment(),
+ false));
+ }
+
+ if (hasFP) {
+ // FP is a callee save register.
+ // This needs saving / restoring in the epilogue / prologue.
+ // Supposedly FP is marked live-in and is killed at the spill. So
+ // don't bother marking it unused.
+ //MF.getRegInfo().setPhysRegUnused(LM32::RFP);
+ // FIXME: shouldn't isSS be true? XCore says no...
+ if ( !isVarArg )
+ FrameIdx = MFrmInf->CreateFixedObject(RC->getSize(), offset, true);
+ else
+ //FIXME: I'm lazy and didn't bother to assign the actual location.
+ FrameIdx = MFrmInf->CreateStackObject(RC->getSize(),
+ RC->getAlignment(), false);
+ MFuncInf->setFPSpillSlot(FrameIdx);
+ }
+}
View
85 lib/Target/LM32/LM32FrameLowering.h
@@ -0,0 +1,85 @@
+//===-- LM32FrameLowering.h - Frame info for LM32 Target ---------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains LM32 frame information that doesn't fit anywhere else
+// cleanly...
+//
+// Based on XCore.
+//===----------------------------------------------------------------------===//
+
+#ifndef LM32FRAMEINFO_H
+#define LM32FRAMEINFO_H
+
+#include "llvm/Target/TargetFrameLowering.h"
+#include "llvm/Target/TargetMachine.h"
+
+namespace llvm {
+ class LM32Subtarget;
+
+ class LM32FrameLowering: public TargetFrameLowering {
+ const LM32Subtarget &Subtarget;
+ public:
+ LM32FrameLowering(const LM32Subtarget &subtarget);
+
+ /// Determine the frame's layout
+ void determineFrameLayout(MachineFunction &MF) const;
+
+ /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
+ /// the function.
+ void emitPrologue(MachineFunction &MF) const;
+ void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
+
+ // Is this frame using a Frame Pointer?
+ bool hasFP(const MachineFunction &MF) const;
+
+ /// hasReservedCallFrame - Under normal circumstances, when a frame pointer is
+ /// not required, we reserve argument space for call sites in the function
+ /// immediately on entry to the current function. This eliminates the need for
+ /// add/sub sp brackets around call sites. Returns true if the call frame is
+ /// included as part of the stack frame.
+ /// LM32 always reserves call frames. eliminateCallFramePseudoInstr() may
+ /// need to change if this does. See ARM for example.
+ ///
+ /// PEI::calculateFrameObjectOffsets() adds maxCallFrameSize if
+ /// hasReservedCallFrame() is true. The stack alignment is set
+ /// in LM32TargetMachine::LM32TargetMachine().
+ /// Some targets (e.g. SPU, PPC) add in the maxCallFrameSize to the
+ /// stacksize manually due to special alignment requirements or other issues.
+ bool hasReservedCallFrame(const MachineFunction &MF) const {
+ // Why wouldn't you do this:
+ // It's not always a good idea to include the call frame as part of the
+ // stack frame. ARM (especially Thumb) has small immediate offset to
+ // address the stack frame. So a large call frame can cause poor codegen
+ // and may even makes it impossible to scavenge a register.
+ //
+ return true;
+ }
+
+
+ /// processFunctionBeforeFrameFinalized - This method is called immediately
+ /// before the specified functions frame layout (MF.getFrameInfo()) is
+ /// finalized. Once the frame is finalized, MO_FrameIndex operands are
+ /// replaced with direct constants. This method is optional.
+ void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
+
+ /// processFunctionBeforeCalleeSavedScan - This method is called immediately
+ /// before PrologEpilogInserter scans the physical registers used to
+ /// determine what callee saved registers should be spilled. This method
+ /// is optional.
+ void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ RegScavenger *RS = NULL) const;
+
+ //! Stack slot size (4 bytes)
+ static int stackSlotSize() {
+ return 4;
+ }
+ };
+}
+
+#endif // LM32FRAMEINFO_H
View
278 lib/Target/LM32/LM32ISelDAGToDAG.cpp
@@ -0,0 +1,278 @@
+//===-- LM32ISelDAGToDAG.cpp - A dag to dag inst selector for LM32 --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an instruction selector for the LM32 target.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "lm32-isel"
+#include "LM32.h"
+#include "LM32MachineFunctionInfo.h"
+#include "LM32RegisterInfo.h"
+#include "LM32Subtarget.h"
+#include "LM32TargetMachine.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Type.h"
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Instruction Selector Implementation
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// LM32DAGToDAGISel - LM32 specific code to select LM32 machine
+// instructions for SelectionDAG operations.
+//===----------------------------------------------------------------------===//
+namespace {
+
+class LM32DAGToDAGISel : public SelectionDAGISel {
+
+ /// TM - Keep a reference to LM32TargetMachine.
+ LM32TargetMachine &TM;
+
+ /// Subtarget - Keep a pointer to the LM32Subtarget around so that we can
+ /// make the right decision when generating code for different targets.
+ const LM32Subtarget &Subtarget;
+
+public:
+ explicit LM32DAGToDAGISel(LM32TargetMachine &tm) :
+ SelectionDAGISel(tm),
+ TM(tm), Subtarget(tm.getSubtarget<LM32Subtarget>()) {}
+
+ // Pass Name
+ virtual const char *getPassName() const {
+ return "LM32 DAG->DAG Pattern Instruction Selection";
+ }
+private:
+ // Include the pieces autogenerated from the target description.
+ #include "LM32GenDAGISel.inc"
+
+ /// getTargetMachine - Return a reference to the TargetMachine, casted
+ /// to the target-specific type.
+ const LM32TargetMachine &getTargetMachine() {
+ return static_cast<const LM32TargetMachine &>(TM);
+ }
+
+ /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
+ /// to the target-specific type.
+ const LM32InstrInfo *getInstrInfo() {
+ return getTargetMachine().getInstrInfo();
+ }
+
+// SDNode *getGlobalBaseReg();
+ SDNode *Select(SDNode *N);
+
+ // Address Selection
+ bool SelectAddrRegImm(SDValue N, SDValue &Disp, SDValue &Base);
+
+ // getI32Imm - Return a target constant with the specified value, of type i32.
+ inline SDValue getI32Imm(unsigned Imm) {
+ return CurDAG->getTargetConstant(Imm, MVT::i32);
+ }
+
+
+};
+
+}
+
+///
+/// This is modeled after SPARC.
+/// Note that the initial pattern in MonarchInstrInfo.td only matches
+/// frameindex.
+/// XCore has a different approach. It also matches add and defines
+/// pseudo-instructions that are eliminated in eliminateFrameIndex.
+///
+bool LM32DAGToDAGISel::
+SelectAddrRegImm(SDValue Addr, SDValue &Base, SDValue &Offset) {
+// errs() << "value type: " << Addr.getValueType().getEVTString();
+ if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
+ Offset = CurDAG->getTargetConstant(0, MVT::i32);
+// errs() << "base result value type: " << Base.getValueType().getEVTString();
+ return true;
+ }
+ if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
+ Addr.getOpcode() == ISD::TargetGlobalAddress)
+ return false; // direct calls.
+
+ // Operand is a result from an ADD
+ if (Addr.getOpcode() == ISD::ADD) {
+ // If the operand is a constant value that fits in a sign-extended 16bit
+ // offset (such that we can just do ADDI R1,4).
+ if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
+ if (isInt<16>(CN->getSExtValue())) {
+ // if the first operand is a frameindex, get the TargetFI node,
+ if (FrameIndexSDNode *FIN =
+ dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
+ //FIXME: why do we change this to a targetFrameIndex?
+ Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
+ } else {
+ Base = Addr.getOperand(0);
+ }
+ Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
+// errs() << "base result value type: " << Base.getValueType().getEVTString();
+ return true;
+ }
+ }
+
+ // These are optimizations. If there's an ADD of a MonarchISD::Lo
+ // (16bit constant) offset it can be incorporated into the ADDri
+ // addressing mode. Note the Hi part must be shifted so it don't work.
+ // E.g. (ld (add lo hi) 0) -> (ld (hi) lo)
+ // also see LowerGlobalAddress etc. for a similar optimization.
+#if 0
+// FIXME: add this back in
+ if (Addr.getOperand(0).getOpcode() == MonarchISD::Lo) {
+ assert(0 && "FIXME: I don't think this will work since Lo is zero-extended and LD will expected sign-extended\n");
+ Base = Addr.getOperand(1);
+ Offset = Addr.getOperand(0).getOperand(0);
+ return true;
+ }
+ if (Addr.getOperand(1).getOpcode() == MonarchISD::Lo) {
+ assert(0 && "FIXME: I don't think this will work since Lo is zero-extended and LD will expected sign-extended\n");
+ Base = Addr.getOperand(0);
+ Offset = Addr.getOperand(1).getOperand(0);
+ return true;
+ }
+#endif
+ }
+ Base = Addr;
+ Offset = CurDAG->getTargetConstant(0, MVT::i32);
+// errs() << "base result value type: " << Base.getValueType().getEVTString();
+ return true;
+}
+
+
+#if 0
+//FIXME: No PIC support.
+/// getGlobalBaseReg - Output the instructions required to put the
+/// GOT address into a register.
+SDNode *LM32DAGToDAGISel::getGlobalBaseReg() {
+//FIXME: not ported to LM32
+assert(0 && "getGlobalBaseReg() not supported.");
+ unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
+ return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
+}
+#endif
+
+/// Select instructions not customized! Used for
+/// expanded, promoted and normal instructions
+/// from MBlaze:
+SDNode* LM32DAGToDAGISel::Select(SDNode *Node) {
+//FIXME: not ported to LM32
+ unsigned Opcode = Node->getOpcode();
+ DebugLoc dl = Node->getDebugLoc();
+
+ // If we have a custom node, we already have selected!
+ if (Node->isMachineOpcode())
+ return NULL;
+
+ ///
+ // Instruction Selection not handled by the auto-generated
+ // tablegen selection should be handled here.
+ ///
+ switch (Opcode) {
+ default: break;
+
+ // Get target GOT address.
+ case ISD::GLOBAL_OFFSET_TABLE: {
+#if 0
+//FIXME: No PIC support.
+ return getGlobalBaseReg();
+#endif
+ assert(0 && "No PIC support.");
+ return Node; // quiet error message
+ }
+
+ case ISD::FrameIndex: {
+ SDValue imm = CurDAG->getTargetConstant(0, MVT::i32);
+ int FI = dyn_cast<FrameIndexSDNode>(Node)->getIndex();
+ EVT VT = Node->getValueType(0);
+// errs() << "ISD::FrameIndex value type: " << VT.getEVTString() << "/n";
+ SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
+ unsigned Opc = LM32::ADDI;
+ if (Node->hasOneUse())
+ return CurDAG->SelectNodeTo(Node, Opc, VT, TFI, imm);
+ return CurDAG->getMachineNode(Opc, dl, VT, TFI, imm);
+ }
+
+
+#if 0
+ /// Handle direct and indirect calls when using PIC. On PIC, when
+ /// GOT is smaller than about 64k (small code) the GA target is
+ /// loaded with only one instruction. Otherwise GA's target must
+ /// be loaded with 3 instructions.
+ case LM32ISD::JmpLink: {
+ if (TM.getRelocationModel() == Reloc::PIC_) {
+ SDValue Chain = Node->getOperand(0);
+ SDValue Callee = Node->getOperand(1);
+ SDValue R20Reg = CurDAG->getRegister(LM32::R20, MVT::i32);
+ SDValue InFlag(0, 0);
+
+ if ((isa<GlobalAddressSDNode>(Callee)) ||
+ (isa<ExternalSymbolSDNode>(Callee)))
+ {
+ /// Direct call for global addresses and external symbols
+ SDValue GPReg = CurDAG->getRegister(LM32::R15, MVT::i32);
+
+ // Use load to get GOT target
+ SDValue Ops[] = { Callee, GPReg, Chain };
+ SDValue Load = SDValue(CurDAG->getMachineNode(LM32::LW, dl,
+ MVT::i32, MVT::Other, Ops, 3), 0);
+ Chain = Load.getValue(1);
+
+ // Call target must be on T9
+ Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Load, InFlag);
+ } else
+ /// Indirect call
+ Chain = CurDAG->getCopyToReg(Chain, dl, R20Reg, Callee, InFlag);
+
+ // Emit Jump and Link Register
+ SDNode *ResNode = CurDAG->getMachineNode(LM32::BRLID, dl, MVT::Other,
+ MVT::Glue, R20Reg, Chain);
+ Chain = SDValue(ResNode, 0);
+ InFlag = SDValue(ResNode, 1);
+ ReplaceUses(SDValue(Node, 0), Chain);
+ ReplaceUses(SDValue(Node, 1), InFlag);
+ return ResNode;
+ }
+ }
+#endif
+ }
+
+ // Select the default instruction
+ SDNode *ResNode = SelectCode(Node);
+
+ DEBUG(errs() << "=> ");
+ if (ResNode == NULL || ResNode == Node)
+ DEBUG(Node->dump(CurDAG));
+ else
+ DEBUG(ResNode->dump(CurDAG));
+ DEBUG(errs() << "\n");
+ return ResNode;
+}
+
+/// createLM32ISelDag - This pass converts a legalized DAG into a
+/// LM32-specific DAG, ready for instruction scheduling.
+FunctionPass *llvm::createLM32ISelDag(LM32TargetMachine &TM) {
+ return new LM32DAGToDAGISel(TM);
+}
View
1,014 lib/Target/LM32/LM32ISelLowering.cpp
@@ -0,0 +1,1014 @@
+//===-- LM32ISelLowering.cpp - LM32 DAG Lowering Implementation -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interfaces that LM32 uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "lm32-lower"
+#include "LM32ISelLowering.h"
+#include "LM32MachineFunctionInfo.h"
+#include "LM32TargetMachine.h"
+#include "LM32TargetObjectFile.h"
+#include "LM32Subtarget.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/CallingConv.h"
+#include "llvm/CodeGen/CallingConvLower.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/SelectionDAGISel.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+const char *LM32TargetLowering::getTargetNodeName(unsigned Opcode) const {
+ switch (Opcode) {
+ case LM32ISD::JmpLink : return "LM32ISD::JmpLink";
+ case LM32ISD::GPRel : return "LM32ISD::GPRel";
+ case LM32ISD::ICmp : return "LM32ISD::ICmp";
+ case LM32ISD::RetFlag : return "LM32ISD::RetFlag";
+ case LM32ISD::Select_CC : return "LM32ISD::Select_CC";
+ case LM32ISD::Hi : return "LM32ISD::Hi";
+ case LM32ISD::Lo : return "LM32ISD::Lo";
+ default : return NULL;
+ }
+}
+
+LM32TargetLowering::LM32TargetLowering(LM32TargetMachine &TM)
+ : TargetLowering(TM, new LM32TargetObjectFile()) {
+ Subtarget = &TM.getSubtarget<LM32Subtarget>();
+
+ // LM32 does not have i1 type, so use i32 for
+ // setcc operations results (slt, sgt, ...).
+ setBooleanContents(ZeroOrOneBooleanContent);
+
+ // Set up the integer register class
+ // See MBlaze for conditional floating point setup if we add that.
+ addRegisterClass(MVT::i32, LM32::GPRRegisterClass);
+
+ // Load extented operations for i1 types must be promoted
+ setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
+ setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
+ setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
+
+ // Sign extended loads must be expanded
+// FIXME: FIXED: are supported
+// setLoadExtAction(ISD::SEXTLOAD, MVT::i8, Expand);
+// setLoadExtAction(ISD::SEXTLOAD, MVT::i16, Expand);
+
+ // There's no extended adds or subtracts.
+ setOperationAction(ISD::ADDC, MVT::i32, Expand);
+ setOperationAction(ISD::ADDE, MVT::i32, Expand);
+ setOperationAction(ISD::SUBC, MVT::i32, Expand);
+ setOperationAction(ISD::SUBE, MVT::i32, Expand);
+
+ // Check if unsigned div/mod are enabled.
+ if (!Subtarget->hasDIV()) {
+ setOperationAction(ISD::UDIV, MVT::i32, Expand);
+ setOperationAction(ISD::UREM, MVT::i32, Expand);
+ }
+
+ // Check if signed div/mod are enabled.
+ if (!Subtarget->hasSDIV()) {
+ setOperationAction(ISD::SDIV, MVT::i32, Expand);
+ setOperationAction(ISD::SREM, MVT::i32, Expand);
+ }
+
+ // LM32 doesn't have a DIV with REM instruction.
+ setOperationAction(ISD::UDIVREM, MVT::i32, Expand);
+ setOperationAction(ISD::SDIVREM, MVT::i32, Expand);
+
+ // If the processor doesn't support multiply then expand it
+ if (!Subtarget->hasMUL()) {
+ setOperationAction(ISD::MUL, MVT::i32, Expand);
+ }
+
+ // LM32 doesn't support 64-bit multiply.
+ setOperationAction(ISD::MULHS, MVT::i32, Expand);
+ setOperationAction(ISD::MULHS, MVT::i64, Expand);
+ setOperationAction(ISD::MULHU, MVT::i32, Expand);
+ setOperationAction(ISD::MULHU, MVT::i64, Expand);
+
+ // Expand unsupported conversions
+ setOperationAction(ISD::BITCAST, MVT::f32, Expand);
+ setOperationAction(ISD::BITCAST, MVT::i32, Expand);
+
+ // Expand SELECT_CC
+//FIXME: need to implement branches
+ setOperationAction(ISD::SELECT_CC, MVT::Other, Expand);
+
+ // LM32 doesn't have MUL_LOHI
+ setOperationAction(ISD::SMUL_LOHI, MVT::i32, Expand);
+ setOperationAction(ISD::UMUL_LOHI, MVT::i32, Expand);
+ setOperationAction(ISD::SMUL_LOHI, MVT::i64, Expand);
+ setOperationAction(ISD::UMUL_LOHI, MVT::i64, Expand);
+
+//FIXME: WHAT is this?
+ // MBlaze: Used by legalize types to correctly generate the setcc result.
+ // Without this, every float setcc comes with a AND/OR with the result,
+ // we don't want this, since the fpcmp result goes to a flag register,
+ // which is used implicitly by brcond and select operations.
+ AddPromotedToType(ISD::SETCC, MVT::i1, MVT::i32);
+// AddPromotedToType(ISD::SELECT, MVT::i1, MVT::i32);
+// AddPromotedToType(ISD::SELECT_CC, MVT::i1, MVT::i32);
+
+ setOperationAction(ISD::SETCC, MVT::i64, Expand);
+ setOperationAction(ISD::SETCC, MVT::f32, Expand);
+ setOperationAction(ISD::SETCC, MVT::f64, Expand);
+
+
+ // LM32 Custom Operations
+ // Custom legalize GlobalAddress nodes into LO/HI parts.
+ setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
+ setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
+ setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
+
+ // Variable Argument support
+ // Use custom implementation for VASTART.
+ // Use the default implementation for VAARG, VACOPY, VAEND.
+ setOperationAction(ISD::VASTART, MVT::Other, Custom);
+ setOperationAction(ISD::VAEND, MVT::Other, Expand);
+ setOperationAction(ISD::VAARG, MVT::Other, Expand);
+ setOperationAction(ISD::VACOPY, MVT::Other, Expand);
+
+
+ // LM32 does not have jump table branches...
+ setOperationAction(ISD::BR_JT, MVT::Other, Expand);
+ // ... so we have to lower the loads from the jump table.
+ setOperationAction(ISD::JumpTable, MVT::i32, Custom);
+ // Expand BR_CC to BRCOND.
+ setOperationAction(ISD::BR_CC, MVT::Other, Expand);
+
+ // Operations not directly supported by LM32.
+ setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
+ setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
+ setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
+ setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
+ setOperationAction(ISD::MEMBARRIER, MVT::Other, Expand);
+ setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Expand);
+ setOperationAction(ISD::FP_ROUND, MVT::f32, Expand);
+ setOperationAction(ISD::FP_ROUND, MVT::f64, Expand);
+ setOperationAction(ISD::CTPOP, MVT::i32, Expand);
+ setOperationAction(ISD::CTTZ, MVT::i32, Expand);
+ setOperationAction(ISD::CTLZ, MVT::i32, Expand);
+ setOperationAction(ISD::CTTZ_ZERO_UNDEF, MVT::i32, Expand);
+ setOperationAction(ISD::CTLZ_ZERO_UNDEF, MVT::i32, Expand);
+
+// FIXME: don't we have ROTL ROTR?
+ setOperationAction(ISD::ROTL , MVT::i32, Expand);
+ setOperationAction(ISD::ROTR , MVT::i32, Expand);
+ setOperationAction(ISD::BSWAP, MVT::i32, Expand);
+
+ // Floating point operations which are not supported
+ setOperationAction(ISD::FREM, MVT::f32, Expand);
+ setOperationAction(ISD::UINT_TO_FP, MVT::i8, Expand);
+ setOperationAction(ISD::UINT_TO_FP, MVT::i16, Expand);
+ setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
+ setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
+ setOperationAction(ISD::FP_ROUND, MVT::f32, Expand);
+ setOperationAction(ISD::FP_ROUND, MVT::f64, Expand);
+ setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
+ setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
+ setOperationAction(ISD::FSUB, MVT::f32, Expand);
+ setOperationAction(ISD::FSIN, MVT::f32, Expand);
+ setOperationAction(ISD::FCOS, MVT::f32, Expand);
+ setOperationAction(ISD::FPOWI, MVT::f32, Expand);
+ setOperationAction(ISD::FPOW, MVT::f32, Expand);
+ setOperationAction(ISD::FPOW, MVT::f64, Expand);
+ setOperationAction(ISD::FLOG, MVT::f32, Expand);
+ setOperationAction(ISD::FLOG2, MVT::f32, Expand);
+ setOperationAction(ISD::FLOG10, MVT::f32, Expand);
+ setOperationAction(ISD::FEXP, MVT::f32, Expand);
+ setOperationAction(ISD::FSQRT, MVT::f64, Expand);
+ setOperationAction(ISD::FSQRT, MVT::f32, Expand);
+
+
+ // We don't have line number support yet.
+ // EH_LABEL - Represents a label in mid basic block used to track
+ // locations needed for debug and exception handling tables. These nodes
+ // take a chain as input and return a chain.
+// FIXME: what does this do?
+ setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
+
+ // Use the default for now
+ setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand);
+ setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
+ setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
+
+ setStackPointerRegisterToSaveRestore(LM32::RSP);
+
+ computeRegisterProperties();
+}
+
+EVT LM32TargetLowering::getSetCCResultType(EVT VT) const {
+ return MVT::i32;
+}
+
+/// getFunctionAlignment - Return the Log2 alignment of this function.
+unsigned LM32TargetLowering::getFunctionAlignment(const Function *) const {
+ return 2;
+}
+
+SDValue LM32TargetLowering::LowerOperation(SDValue Op,
+ SelectionDAG &DAG) const {
+ switch (Op.getOpcode())
+ {
+ case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
+ case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
+ case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
+ case ISD::JumpTable: return LowerJumpTable(Op, DAG);
+ case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
+ case ISD::VASTART: return LowerVASTART(Op, DAG);
+ }
+ return SDValue();
+}
+
+//===----------------------------------------------------------------------===//
+// Lower helper functions
+//===----------------------------------------------------------------------===//
+MachineBasicBlock*
+LM32TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
+ MachineBasicBlock *MBB)
+ const {
+ switch (MI->getOpcode()) {
+ default: assert(false && "Unexpected instr type to insert");
+/*
+
+ case LM32::ShiftRL:
+ case LM32::ShiftRA:
+ case LM32::ShiftL:
+ return EmitCustomShift(MI, MBB);
+
+ case LM32::Select_FCC:
+ case LM32::Select_CC:
+ return EmitCustomSelect(MI, MBB);
+
+ case LM32::CAS32:
+ case LM32::SWP32:
+ case LM32::LAA32:
+ case LM32::LAS32:
+ case LM32::LAD32:
+ case LM32::LAO32:
+ case LM32::LAX32:
+ case LM32::LAN32:
+ return EmitCustomAtomic(MI, MBB);
+
+ case LM32::MEMBARRIER:
+ // The Microblaze does not need memory barriers. Just delete the pseudo
+ // instruction and finish.
+ MI->eraseFromParent();
+ return MBB;
+*/
+ }
+}
+
+MachineBasicBlock*
+LM32TargetLowering::EmitCustomSelect(MachineInstr *MI,
+ MachineBasicBlock *MBB) const {
+ const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+ DebugLoc dl = MI->getDebugLoc();
+
+ // To "insert" a SELECT_CC instruction, we actually have to insert the
+ // diamond control-flow pattern. The incoming instruction knows the
+ // destination vreg to set, the condition code register to branch on, the
+ // true/false values to select between, and a branch opcode to use.
+ const BasicBlock *LLVM_BB = MBB->getBasicBlock();
+ MachineFunction::iterator It = MBB;
+ ++It;
+
+ // thisMBB:
+ // ...
+ // TrueVal = ...
+ // setcc r1, r2, r3
+ // bNE r1, r0, copy1MBB
+ // fallthrough --> copy0MBB
+ MachineFunction *F = MBB->getParent();
+ MachineBasicBlock *flsBB = F->CreateMachineBasicBlock(LLVM_BB);
+ MachineBasicBlock *dneBB = F->CreateMachineBasicBlock(LLVM_BB);
+
+ unsigned Opc;
+ switch (MI->getOperand(4).getImm()) {
+ default: llvm_unreachable("Unknown branch condition");
+//FIXME:
+#if 0
+ case LM32CC::EQ: Opc = LM32::BEQID; break;
+ case LM32CC::NE: Opc = LM32::BNEID; break;
+ case LM32CC::GT: Opc = LM32::BGTID; break;
+ case LM32CC::LT: Opc = LM32::BLTID; break;
+ case LM32CC::GE: Opc = LM32::BGEID; break;
+ case LM32CC::LE: Opc = LM32::BLEID; break;
+#endif
+ }
+
+ F->insert(It, flsBB);
+ F->insert(It, dneBB);
+
+ // Transfer the remainder of MBB and its successor edges to dneBB.
+ dneBB->splice(dneBB->begin(), MBB,
+ llvm::next(MachineBasicBlock::iterator(MI)),
+ MBB->end());
+ dneBB->transferSuccessorsAndUpdatePHIs(MBB);
+
+ MBB->addSuccessor(flsBB);
+ MBB->addSuccessor(dneBB);
+ flsBB->addSuccessor(dneBB);
+
+ BuildMI(MBB, dl, TII->get(Opc))
+ .addReg(MI->getOperand(3).getReg())
+ .addMBB(dneBB);
+
+ // sinkMBB:
+ // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
+ // ...
+ //BuildMI(dneBB, dl, TII->get(LM32::PHI), MI->getOperand(0).getReg())
+ // .addReg(MI->getOperand(1).getReg()).addMBB(flsBB)
+ // .addReg(MI->getOperand(2).getReg()).addMBB(BB);
+
+ BuildMI(*dneBB, dneBB->begin(), dl,
+ TII->get(LM32::PHI), MI->getOperand(0).getReg())
+ .addReg(MI->getOperand(2).getReg()).addMBB(flsBB)
+ .addReg(MI->getOperand(1).getReg()).addMBB(MBB);
+
+ MI->eraseFromParent(); // The pseudo instruction is gone now.
+ return dneBB;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Misc Lower Operation implementation
+//===----------------------------------------------------------------------===//
+//
+
+SDValue LM32TargetLowering::LowerSELECT_CC(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDValue LHS = Op.getOperand(0);
+ SDValue RHS = Op.getOperand(1);
+ SDValue TrueVal = Op.getOperand(2);
+ SDValue FalseVal = Op.getOperand(3);
+ DebugLoc dl = Op.getDebugLoc();
+ unsigned Opc;
+
+DAG.viewGraph();
+
+ SDValue CompareFlag;
+ if (LHS.getValueType() == MVT::i32) {
+ Opc = LM32ISD::Select_CC;
+ CompareFlag = DAG.getNode(LM32ISD::ICmp, dl, MVT::i32, LHS, RHS)
+ .getValue(1);
+ } else {
+ llvm_unreachable("Cannot lower select_cc with unknown type");
+ }
+
+ return DAG.getNode(Opc, dl, TrueVal.getValueType(), TrueVal, FalseVal,
+ CompareFlag);
+}
+
+// Modeled on Sparc LowerGlobalAddress.
+SDValue LM32TargetLowering::
+LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
+{
+ const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
+ DebugLoc dl = Op.getDebugLoc();
+ SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32);
+ // From XCore: If it's a debug information descriptor, don't mess with it.
+//FIXME: The following is from xcore but doesn't appear to work there either.
+// Once that is fixed we can uncomment this:
+// the following can trigger this:
+// int puts(const char * format);
+// int main(int argc, char ** argv) { puts("hello world\n"); return(5); }
+#if 0
+ if (DAG.isVerifiedDebugInfoDesc(Op))
+ return GA;
+#endif
+ SDValue Hi = DAG.getNode(LM32ISD::Hi, dl, MVT::i32, GA);
+ SDValue Lo = DAG.getNode(LM32ISD::Lo, dl, MVT::i32, GA);
+ /* FIXME: revisit this and see if it gets optimized:
+ // The goal here was to incorporate the "ADD" into the
+ // LD but it doesn't work since Monarch:Lo is unsigned
+ // and ADDI expectes a signed operand.
+ // See MonarchISelDAGToDAG.cpp (MonarchDAGToDAGISel::SelectADDRri)
+ // for a similar ADD optimiztion.
+ //// I believe the order of Hi/Lo is important. I think
+ //// the Hi should be done first, then the Lo can be added in
+ //// as an offset in a future ST or LD (or other) instruction
+ //// and the ADD node we're creating here removed.
+ //// Therefore the Hi part should be loaded arithmetically (@ha)
+ //// to allow the offset to be added (instead of or'ed).
+ //// SelectADDRri it looks for MonarchISD::Lo and makes
+ //// this optimization (although it looks in both operands).
+ //
+ // Note that LM32 assembler does not have an @ha equivalent.
+ // The M32R "shigh" GAS directive is what we need.
+ */
+ //return DAG.getNode(ISD::ADD, dl, MVT::i32, Lo, Hi);
+ return DAG.getNode(ISD::OR, dl, MVT::i32, Lo, Hi);
+}
+
+
+SDValue LM32TargetLowering::
+LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
+ llvm_unreachable("TLS not implemented for LM32.");
+ return SDValue(); // Not reached
+}
+
+// Derived from PPC.
+SDValue LM32TargetLowering::
+LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
+ DEBUG(assert(Op.getValueType() == MVT::i32 && "pointers should be 32 bits."));
+ DebugLoc dl = Op.getDebugLoc();
+ JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
+ SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), MVT::i32);
+ SDValue Hi = DAG.getNode(LM32ISD::Hi, dl, MVT::i32, JTI);
+ SDValue Lo = DAG.getNode(LM32ISD::Lo, dl, MVT::i32, JTI);
+
+ // We don't support non-static relo models yet.
+ if (DAG.getTarget().getRelocationModel() == Reloc::Static ) {
+ // Generate non-pic code that has direct accesses to the constant pool.
+ // The address of the global is just (hi(&g)+lo(&g)).
+ return DAG.getNode(ISD::OR, dl, MVT::i32, Lo, Hi);
+ } else {
+ llvm_unreachable("JumpTables are only supported in static mode");
+ }
+
+ return Op; // notreached
+}
+
+
+SDValue LM32TargetLowering::
+LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
+{
+ ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
+ // FIXME: there isn't really any debug info here
+ DebugLoc dl = Op.getDebugLoc();
+ const Constant *C = N->getConstVal();
+ SDValue CP = DAG.getTargetConstantPool(C, MVT::i32, N->getAlignment());
+ SDValue Hi = DAG.getNode(LM32ISD::Hi, dl, MVT::i32, CP);
+ SDValue Lo = DAG.getNode(LM32ISD::Lo, dl, MVT::i32, CP);
+ // See note above in LowerGlobalAddress about operands.
+ return DAG.getNode(ISD::OR, dl, MVT::i32, Lo, Hi);
+ //return DAG.getNode(ISD::ADD, dl, MVT::i32, Lo, Hi);
+}
+
+SDValue LM32TargetLowering::LowerVASTART(SDValue Op,
+ SelectionDAG &DAG) const {
+ MachineFunction &MF = DAG.getMachineFunction();
+ LM32FunctionInfo *FuncInfo = MF.getInfo<LM32FunctionInfo>();
+
+ DebugLoc dl = Op.getDebugLoc();
+ SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
+ getPointerTy());
+
+ // vastart just stores the address of the VarArgsFrameIndex slot into the
+ // memory location argument.
+ const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
+ return DAG.getStore(Op.getOperand(0), dl, FI, Op.getOperand(1),
+ MachinePointerInfo(SV),
+ false, false, 0);
+}
+
+//===----------------------------------------------------------------------===//
+// Calling Convention Implementation
+//
+// The lower operations present on calling convention works on this order:
+// LowerCall (virt regs --> phys regs, virt regs --> stack)
+// LowerFormalArguments (phys --> virt regs, stack --> virt regs)
+// LowerReturn (virt regs --> phys regs)
+// LowerCall (phys regs --> virt regs)
+//
+//===----------------------------------------------------------------------===//
+
+#include "LM32GenCallingConv.inc"
+
+//===----------------------------------------------------------------------===//
+// Call Calling Convention Implementation
+//===----------------------------------------------------------------------===//
+// This is modeled after XCore code with MIPS and others influences.
+// For XCore ABI see https://www.xmos.com/system/files/abi87.pdf
+// https://www.xmos.com/support/documentation/software
+// For mips eabi see http://www.cygwin.com/ml/binutils/2003-06/msg00436.html
+// Elements may have been used from SparcTargetLowering::LowerArguments.
+//===----------------------------------------------------------------------===//
+/// Monarch call implementation
+/// LowerCall - This hook must be implemented to lower calls into the
+/// the specified DAG. The outgoing arguments to the call are described
+/// by the OutVals array, and the values to be returned by the call are
+/// described by the Ins array. The implementation should fill in the
+/// InVals array with legal-type return values from the call, and return
+/// the resulting token chain value.
+///
+/// The isTailCall flag here is normative. If it is true, the
+/// implementation must emit a tail call. The
+/// IsEligibleForTailCallOptimization hook should be used to catch
+/// cases that cannot be handled.
+///
+
+/// LowerCall - functions arguments are copied from virtual regs to
+/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
+/// TODO: isVarArg, isTailCall.
+SDValue LM32TargetLowering::
+LowerCall(SDValue Chain, SDValue Callee, CallingConv::ID CallConv,
+ bool isVarArg, bool &isTailCall,
+ const SmallVectorImpl<ISD::OutputArg> &Outs,
+ const SmallVectorImpl<SDValue> &OutVals,
+ const SmallVectorImpl<ISD::InputArg> &Ins,
+ DebugLoc dl, SelectionDAG &DAG,
+ SmallVectorImpl<SDValue> &InVals) const {
+
+ // For now, only CallingConv::C implemented
+ if (CallConv != CallingConv::Fast && CallConv != CallingConv::C)
+ llvm_unreachable("Unsupported calling convention");
+
+ // LM32 does not yet support tail call optimization
+ isTailCall = false;
+
+ // Analyze operands of the call, assigning locations to each operand.
+//FIXME: Check this 16 argument number
+ SmallVector<CCValAssign, 16> ArgLocs;
+ CCState CCInfo(CallConv, isVarArg, DAG.getMachineFunction(),
+ getTargetMachine(), ArgLocs, *DAG.getContext());
+
+ CCInfo.AnalyzeCallOperands(Outs, CC_LM32);
+
+ // Get a count of how many bytes are to be pushed on the stack.
+ unsigned NumBytes = CCInfo.getNextStackOffset();
+
+ // Comment from ARM: Adjust the stack pointer for the new arguments...
+ // These operations are automatically eliminated by the prolog/epilog pass
+ Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes, true));
+