[llvm-commits] [llvm-gcc-4.2] r71655 - in /llvm-gcc-4.2/trunk: config.sub configure configure.in gcc/Makefile.in gcc/config.gcc gcc/config/tce/ gcc/config/tce/t-tce gcc/config/tce/tce.c gcc/config/tce/tce.h gcc/config/tce/tce.md

Duncan Sands baldrick at free.fr
Wed May 13 06:10:25 PDT 2009


Author: baldrick
Date: Wed May 13 08:10:04 2009
New Revision: 71655

URL: http://llvm.org/viewvc/llvm-project?rev=71655&view=rev
Log:
Add TCE target.  Patch by Mikael Lepistö.

Added:
    llvm-gcc-4.2/trunk/gcc/config/tce/
    llvm-gcc-4.2/trunk/gcc/config/tce/t-tce
    llvm-gcc-4.2/trunk/gcc/config/tce/tce.c
    llvm-gcc-4.2/trunk/gcc/config/tce/tce.h
    llvm-gcc-4.2/trunk/gcc/config/tce/tce.md
Modified:
    llvm-gcc-4.2/trunk/config.sub
    llvm-gcc-4.2/trunk/configure
    llvm-gcc-4.2/trunk/configure.in
    llvm-gcc-4.2/trunk/gcc/Makefile.in
    llvm-gcc-4.2/trunk/gcc/config.gcc

Modified: llvm-gcc-4.2/trunk/config.sub
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/config.sub?rev=71655&r1=71654&r2=71655&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/config.sub (original)
+++ llvm-gcc-4.2/trunk/config.sub Wed May 13 08:10:04 2009
@@ -1154,6 +1154,11 @@
 	pmac | pmac-mpw)
 		basic_machine=powerpc-apple
 		;;
+# LLVM LOCAL begin - TCE target
+ 	tce*)
+ 		basic_machine=tce-
+ 		;;
+# LLVM LOCAL end - TCE target
 	*-unknown)
 		# Make sure to match an already-canonicalized machine name.
 		;;
@@ -1355,6 +1360,10 @@
 	-zvmoe)
 		os=-zvmoe
 		;;
+# LLVM LOCAL begin - TCE target
+ 	-llvm*)
+        ;;
+# LLVM LOCAL end - TCE target
 	-none)
 		;;
 	*)

Modified: llvm-gcc-4.2/trunk/configure
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/configure?rev=71655&r1=71654&r2=71655&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/configure (original)
+++ llvm-gcc-4.2/trunk/configure Wed May 13 08:10:04 2009
@@ -1640,6 +1640,11 @@
   spu-*-*)
     skipdirs="target-libiberty target-libssp"
     ;;
+# LLVM LOCAL begin - TCE target
+  tce-*-*)
+    skipdirs="target-libssp target-libstdc++-v3"
+    ;;
+# LLVM LOCAL end - TCE target
   v810-*-*)
     noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
     ;;

Modified: llvm-gcc-4.2/trunk/configure.in
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/configure.in?rev=71655&r1=71654&r2=71655&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/configure.in (original)
+++ llvm-gcc-4.2/trunk/configure.in Wed May 13 08:10:04 2009
@@ -800,6 +800,11 @@
   spu-*-*)
     skipdirs="target-libiberty target-libssp"
     ;;
+# LLVM LOCAL begin - TCE target
+  tce-*-*)
+    skipdirs="target-libssp target-libstdc++-v3"
+    ;;  
+# LLVM LOCAL end - TCE target
   v810-*-*)
     noconfigdirs="$noconfigdirs bfd binutils gas gcc gdb ld target-libstdc++-v3 opcodes target-libgloss ${libgcj}"
     ;;

Modified: llvm-gcc-4.2/trunk/gcc/Makefile.in
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/Makefile.in?rev=71655&r1=71654&r2=71655&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/Makefile.in (original)
+++ llvm-gcc-4.2/trunk/gcc/Makefile.in Wed May 13 08:10:04 2009
@@ -1152,6 +1152,7 @@
     sparc-*-*) echo sparc;; \
     sparcv9-*-*) echo sparc;; \
     spu-*-*) echo cellspu;; \
+    tce-*-*) echo tce;; \
    esac
 LLVMTARGETOBJ := $(shell $(LLVMTARGETCOMPONENT))
 
@@ -1159,6 +1160,12 @@
 $(error Unsuported LLVM Target $(target))
 endif
 
+# TCE is external backend so we just set target obj to be all to get all 
+# libs to be included to LLVMLIBFILES list 
+ifeq ($(LLVMTARGETOBJ),tce)
+LLVMTARGETOBJ := all
+endif
+
 # If in BUILD_LLVM_INTO_A_DYLIB mode, always link in the x86/ppc backends.
 # See below for more details.
 ifdef BUILD_LLVM_INTO_A_DYLIB
@@ -1184,6 +1191,7 @@
 # libraries change the tools should be relinked.
 LIBDEPS          += $(LLVMLIBFILES)
 LLVMBACKENDFILES := $(LLVMLIBFILES)
+# LLVM LOCAL end
 
 # LLVM LOCAL begin - set DYLD path
 SET_DYLIB_PATH=0

Modified: llvm-gcc-4.2/trunk/gcc/config.gcc
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config.gcc?rev=71655&r1=71654&r2=71655&view=diff

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config.gcc (original)
+++ llvm-gcc-4.2/trunk/gcc/config.gcc Wed May 13 08:10:04 2009
@@ -2425,6 +2425,19 @@
 	md_file=arm/arm.md
 	extra_modes=arm/arm-modes.def
 	;;
+# LLVM LOCAL begin - TCE target
+tce*-llvm*)
+	use_fixproto=yes
+    use_collect2=no
+
+# this didn't have any effect - tce.md was still needed
+#   md_file=""
+
+	tm_p_file=""
+	tmake_file="tce/t-tce"
+   	tm_file="dbxelf.h elfos.h svr4.h ${tm_file}"
+   	;;
+# LLVM LOCAL end - TCE target
 v850e1-*-*)
 	target_cpu_default="TARGET_CPU_v850e1"
 	tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"

Added: llvm-gcc-4.2/trunk/gcc/config/tce/t-tce
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/tce/t-tce?rev=71655&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/tce/t-tce (added)
+++ llvm-gcc-4.2/trunk/gcc/config/tce/t-tce Wed May 13 08:10:04 2009
@@ -0,0 +1,27 @@
+# LLVM LOCAL begin - TCE target
+
+# Makes --emit-llvm to be added to gcc command by default and 
+# sets tools to use llvm-ld, llvm-as etc. as binutils for copiler.
+# TODO: IMPLEMENT THIS DEFINE 
+# (maybe could be useful for other new bitcode only targets)
+ALWAYS_EMIT_LLVM=1
+
+# we want to output bitcode
+TARGET_LIBGCC2_CFLAGS = --emit-llvm 
+
+# These does not seem to work correctly. 
+# For some reason overrides does not reach
+# e.g. libgcc2 compilation
+LD_FOR_TARGET = llvm-ld
+AS_FOR_TARGET = llvm-as
+NM_FOR_TARGET = llvm-nm
+RANLIB_FOR_TARGET = llvm-ranlib
+AR_FOR_TARGET = llvm-ar
+
+# So instead you have to give these for main level configure as follows
+
+# AR_FOR_TARGET=`which llvm-ar` RANLIB_FOR_TARGET=`which llvm-ranlib` \
+# AS_FOR_TARGET=`which llvm-as` LD_FOR_TARGET=`which llvm-ld` \
+# NM_FOR_TARGET=`which llvm-nm`
+
+# LLVM LOCAL end - TCE target

Added: llvm-gcc-4.2/trunk/gcc/config/tce/tce.c
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/tce/tce.c?rev=71655&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/tce/tce.c (added)
+++ llvm-gcc-4.2/trunk/gcc/config/tce/tce.c Wed May 13 08:10:04 2009
@@ -0,0 +1,29 @@
+// LLVM LOCAL begin - TCE target
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "rtl.h"
+#include "regs.h"
+#include "hard-reg-set.h"
+#include "real.h"
+#include "insn-config.h"
+#include "conditions.h"
+#include "insn-attr.h"
+#include "flags.h"
+#include "recog.h"
+#include "tree.h"
+#include "output.h"
+#include "expr.h"
+#include "obstack.h"
+#include "except.h"
+#include "function.h"
+#include "toplev.h"
+#include "tm_p.h"
+#include "target.h"
+#include "target-def.h"
+
+struct gcc_target targetm = TARGET_INITIALIZER;
+
+// LLVM LOCAL end - TCE target

Added: llvm-gcc-4.2/trunk/gcc/config/tce/tce.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/tce/tce.h?rev=71655&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/tce/tce.h (added)
+++ llvm-gcc-4.2/trunk/gcc/config/tce/tce.h Wed May 13 08:10:04 2009
@@ -0,0 +1,845 @@
+// LLVM LOCAL begin - TCE target
+/*
+Definitions of TCE target 
+Mikael Lepistö (mikael.lepisto at tut.fi)
+based on fr30 target by Cygnus Solutions.
+
+This is part of minimal implementation for being able to
+compile llvm-gcc with tce-llvm target.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* This declaration should be present.  */
+extern int target_flags;
+
+#define REAL_LD_FILE_NAME "llvm-ld"
+#define REAL_NM_FILE_NAME "llvm-nm"
+#define DEAFULT_LINKER "llvm-ld"
+
+/* To make llvm-backend.cpp recognice us ok... */
+#define LLVM_OVERRIDE_TARGET_ARCH() "mips"
+
+
+#define TARGET_CPU_CPP_BUILTINS()	   \
+  do						           \
+    {						           \
+      builtin_define_std ("tce");	   \
+      builtin_define_std ("__TCE__");  \
+      builtin_define_std ("__TCE_V1__");  \
+    }						           \
+   while (0)
+
+/* The -Q options from svr4.h aren't understood and must be removed.  */
+#undef  ASM_SPEC
+#define ASM_SPEC \
+  "%{v:-V} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*} -f"
+
+#undef LINK_SPEC
+#define LINK_SPEC "-disable-opt -disable-internalize"
+
+/**
+ * For C++ support there migh be necessary to add  crt1.o also..
+ */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC "crt0.o%s"
+
+#undef ENDFILE_SPEC
+/*
+#define ENDFILE_SPEC "libc.a%s libnosys.a%s libm.a%s emulation_functions.o%s crtend.o%s"
+*/
+
+/* emulation functions are linked in lowermissing pass */
+#define ENDFILE_SPEC "libc.a%s libnosys.a%s libm.a%s crtend.o%s"
+
+/* There is no default multilib. */
+#undef MULTILIB_DEFAULTS      
+
+/**
+ * Future switches... 
+ * 
+ * Type sizes, endianess, registers...
+ */
+/*
+#define TARGET_SWITCHES \
+{						\
+  { "", 0, "" }	\
+}
+*/
+
+/*
+  Turn off replacement of mallocs and free calls with
+  corresponding llvm assembler instructions.
+-ffreestanding 
+    flag_freestanding = 1;  didn't work.. has to be switch...
+-fno-unit-at-a-time
+    flag_unit_at_a_time = 0;  give this also to compiler...
+*/
+#undef  OVERRIDE_OPTIONS
+#define OVERRIDE_OPTIONS \
+{                        \
+    emit_llvm = 1;       \
+}
+
+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE)  \
+  do						               \
+    {						               \
+    }						               \
+  while (0)
+
+#define TARGET_VERSION fprintf (stderr, " (tce)");
+
+/* Number of hardware registers known to the compiler.  They receive numbers 0
+   through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
+   really is assigned the number `FIRST_PSEUDO_REGISTER'.  */
+#define FIRST_FP_REGISTER	512
+
+#define FIRST_PSEUDO_REGISTER	1024
+
+
+/* A C type for declaring a variable that is used as the first argument of
+   `FUNCTION_ARG' and other related values.  For some target machines, the type
+   `int' suffices and can hold the number of bytes of argument so far.
+
+   There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
+   that have been passed on the stack.  The compiler has other variables to
+   keep track of that.  For target machines on which all arguments are passed
+   on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
+   however, the data structure must exist and should not be empty, so use
+   `int'.  */
+/* On the FR30 this value is an accumulating count of the number of argument
+   registers that have been filled with argument values, as opposed to say,
+   the number of bytes of argument accumulated so far.  */
+#define CUMULATIVE_ARGS int
+
+/*{{{  Register Classes.  */ 
+
+/* An enumeral type that must be defined with all the register class names as
+   enumeral values.  `NO_REGS' must be first.  `ALL_REGS' must be the last
+   register class, followed by one more enumeral value, `LIM_REG_CLASSES',
+   which is not a register class but rather tells how many classes there are.
+
+   Each register class has a number, which is the value of casting the class
+   name to type `int'.  The number serves as an index in many of the tables
+   described below.  */
+enum reg_class
+{
+  NO_REGS,
+  INT_REGS,		/* i.e. all the general hardware registers on the FR30 */
+  FP_REGS,
+  ALL_REGS,
+  LIM_REG_CLASSES
+};
+
+#define N_REG_CLASSES 	((int) LIM_REG_CLASSES)
+
+#define STRICT_ALIGNMENT 1
+
+/*{{{  Layout of Source Language Data Types.  */ 
+
+#define CHAR_TYPE_SIZE			 8
+#define SHORT_TYPE_SIZE 	    16
+#define INT_TYPE_SIZE 		    32
+#define LONG_TYPE_SIZE 		    32
+
+/* Enable this if you like to start fixing 64bit ISEL issues */
+#if 0
+#define LONG_LONG_TYPE_SIZE 	64
+#else
+#define LONG_LONG_TYPE_SIZE 	32
+/* to omit compilation of libgcc2 (it wont work without long long 64bit) */
+#define LIBGCC2_UNITS_PER_WORD  8 
+#endif
+
+#define FLOAT_TYPE_SIZE 	    32
+#define DOUBLE_TYPE_SIZE 	    32
+#define LONG_DOUBLE_TYPE_SIZE 	32
+
+#define POINTER_SIZE			32
+
+#define DEFAULT_SIGNED_CHAR 1
+
+/*{{{  Storage Layout.  */ 
+#define BITS_BIG_ENDIAN  1
+#define BYTES_BIG_ENDIAN 1
+#define WORDS_BIG_ENDIAN 1
+#define UNITS_PER_WORD 	 4
+
+#define FUNCTION_BOUNDARY 32
+#define BIGGEST_ALIGNMENT 64
+#define STACK_BOUNDARY    32
+
+/* A C expression for the size in bytes of the trampoline, as an integer.  */
+#define TRAMPOLINE_SIZE 18
+
+/* The register number of the stack pointer register, which must also be a
+   fixed register according to `FIXED_REGISTERS'.  On most machines, the
+   hardware determines which register this is.  */
+#define STACK_POINTER_REGNUM	1
+
+/* The register number of the frame pointer register, which is used to access
+   automatic variables in the stack frame.  On some machines, the hardware
+   determines which register this is.  On other machines, you can choose any
+   register you wish for this purpose.  */
+#define FRAME_POINTER_REGNUM	6
+
+/* The register number of the arg pointer register, which is used to access the
+   function's argument list.  On some machines, this is the same as the frame
+   pointer register.  On some machines, the hardware determines which register
+   this is.  On other machines, you can choose any register you wish for this
+   purpose.  If this is not the same register as the frame pointer register,
+   then you must mark it as a fixed register according to `FIXED_REGISTERS', or
+   arrange to be able to eliminate it.  */
+#define ARG_POINTER_REGNUM 2
+
+/* The first register that can contain the arguments to a function.  */
+#define FIRST_ARG_REGNUM	 2
+
+/* The register that contains the result of a function call.  */
+#define RETURN_VALUE_REGNUM	 0
+
+#define EH_RETURN_DATA_REGNO(N) (RETURN_VALUE_REGNUM)
+
+#define DWARF_FRAME_REGNUM(REG) (REG)
+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (1)
+
+/* A C expression that is nonzero if REGNO is the number of a hard register in
+   which function arguments are sometimes passed.  This does *not* include
+   implicit arguments such as the static chain and the structure-value address.
+   On many machines, no registers can be used for this purpose since all
+   function arguments are pushed on the stack.  */
+/* #define FUNCTION_ARG_REGNO_P(REGNO) */
+#define FUNCTION_ARG_REGNO_P(REGNO) ((REGNO) >= FIRST_ARG_REGNUM)
+
+/* A C expression that is nonzero if it is permissible to store a value of mode
+   MODE in hard register number REGNO (or in several registers starting with
+   that one).  */
+#define HARD_REGNO_MODE_OK(REGNO, MODE) 1
+
+#define PARM_BOUNDARY 32
+
+/* A C statement to initialize the variable parts of a trampoline.  ADDR is an
+   RTX for the address of the trampoline; FNADDR is an RTX for the address of
+   the nested function; STATIC_CHAIN is an RTX for the static chain value that
+   should be passed to the function when it is called.  */
+#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, STATIC_CHAIN)			\
+do										\
+{										\
+  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (ADDR, 4)), STATIC_CHAIN);\
+  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (ADDR, 12)), FNADDR);	\
+} while (0);
+
+
+/* A macro whose definition is the name of the class to which a valid base
+   register must belong.  A base register is one used in an address which is
+   the register value plus a displacement.  */
+#define BASE_REG_CLASS 	INT_REGS
+
+#define GENERAL_REGS 	INT_REGS
+
+/*{{{  Describing Relative Costs of Operations */ 
+
+/* Define this macro as a C expression which is nonzero if accessing less than
+   a word of memory (i.e. a `char' or a `short') is no faster than accessing a
+   word of memory, i.e., if such access require more than one instruction or if
+   there is no difference in cost between byte and (aligned) word loads.
+
+   When this macro is not defined, the compiler will access a field by finding
+   the smallest containing object; when it is defined, a fullword load will be
+   used if alignment permits.  Unless bytes accesses are faster than word
+   accesses, using word accesses is preferable since it may eliminate
+   subsequent memory access if subsequent accesses occur to other fields in the
+   same word of the structure, but to different bytes.  */
+#define SLOW_BYTE_ACCESS 1
+
+/* A number, the maximum number of registers that can appear in a valid memory
+   address.  Note that it is up to you to specify a value equal to the maximum
+   number that `GO_IF_LEGITIMATE_ADDRESS' would ever accept.  */
+#define MAX_REGS_PER_ADDRESS 1
+
+/* A C string constant for text to be output before each `asm' statement or
+   group of consecutive ones.  Normally this is `"#APP"', which is a comment
+   that has no effect on most assemblers but tells the GNU assembler that it
+   must check the lines that follow for all valid assembler constructs.  */
+#define ASM_APP_ON "#APP\n"
+
+/* A C string constant for text to be output after each `asm' statement or
+   group of consecutive ones.  Normally this is `"#NO_APP"', which tells the
+   GNU assembler to resume making the time-saving assumptions that are valid
+   for ordinary compiler output.  */
+#define ASM_APP_OFF "#NO_APP\n"
+
+/* A C expression which is nonzero if a function must have and use a frame
+   pointer.  This expression is evaluated in the reload pass.  If its value is
+   nonzero the function will have a frame pointer.
+
+   The expression can in principle examine the current function and decide
+   according to the facts, but on most machines the constant 0 or the constant
+   1 suffices.  Use 0 when the machine allows code to be generated with no
+   frame pointer, and doing so saves some time or space.  Use 1 when there is
+   no possible advantage to avoiding a frame pointer.
+
+   In certain cases, the compiler does not know how to produce valid code
+   without a frame pointer.  The compiler recognizes those cases and
+   automatically gives the function a frame pointer regardless of what
+   `FRAME_POINTER_REQUIRED' says.  You don't need to worry about them.
+
+   In a function that does not require a frame pointer, the frame pointer
+   register can be allocated for ordinary usage, unless you mark it as a fixed
+   register.  See `FIXED_REGISTERS' for more information.  */
+/* #define FRAME_POINTER_REQUIRED 0 */
+#define FRAME_POINTER_REQUIRED \
+     (flag_omit_frame_pointer == 0 || current_function_pretend_args_size > 0)
+
+/* Offset from the frame pointer to the first local variable slot to be
+   allocated.
+
+   If `FRAME_GROWS_DOWNWARD', find the next slot's offset by subtracting the
+   first slot's length from `STARTING_FRAME_OFFSET'.  Otherwise, it is found by
+   adding the length of the first slot to the value `STARTING_FRAME_OFFSET'.  */
+/* #define STARTING_FRAME_OFFSET -4 */
+#define STARTING_FRAME_OFFSET 0
+
+/* A macro whose definition is the name of the class to which a valid index
+   register must belong.  An index register is one used in an address where its
+   value is either multiplied by a scale factor or added to another register
+   (as well as added to a displacement).  */
+#define INDEX_REG_CLASS INT_REGS
+
+/* A C expression whose value is a register class containing hard register
+   REGNO.  In general there is more than one such class; choose a class which
+   is "minimal", meaning that no smaller class also contains the register.  */
+#define REGNO_REG_CLASS(REGNO) 	((REGNO > FIRST_FP_REGISTER )?(INT_REGS):(FP_REGS))
+
+/* A C expression that is nonzero if X is a legitimate constant for an
+   immediate operand on the target machine.  You can assume that X satisfies
+   `CONSTANT_P', so you need not check this.  In fact, `1' is a suitable
+   definition for this macro on machines where anything `CONSTANT_P' is valid.  */
+#define LEGITIMATE_CONSTANT_P(X) 1
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)			\
+  do									\
+    {									\
+      if (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))			\
+        goto LABEL;							\
+      if (GET_CODE (X) == PLUS						\
+	  && ((MODE) == SImode || (MODE) == SFmode)			\
+	  && XEXP (X, 0) == stack_pointer_rtx				\
+	  && GET_CODE (XEXP (X, 1)) == CONST_INT			\
+	  && IN_RANGE (INTVAL (XEXP (X, 1)), 0, (1 <<  6) - 4))		\
+	goto LABEL;							\
+      if (GET_CODE (X) == PLUS						\
+	  && ((MODE) == SImode || (MODE) == SFmode)			\
+	  && GET_CODE (XEXP (X, 0)) == REG \
+          && (REGNO (XEXP (X, 0)) == FRAME_POINTER_REGNUM \
+           || REGNO (XEXP (X, 0)) == ARG_POINTER_REGNUM) \
+	  && GET_CODE (XEXP (X, 1)) == CONST_INT			\
+	  && IN_RANGE (INTVAL (XEXP (X, 1)), -(1 << 9), (1 <<  9) - 4))	\
+        goto LABEL;							\
+    }									\
+  while (0)
+
+/* A C expression that is nonzero if X (assumed to be a `reg' RTX) is valid for
+   use as a base register.  For hard registers, it should always accept those
+   which the hardware permits and reject the others.  Whether the macro accepts
+   or rejects pseudo registers must be controlled by `REG_OK_STRICT' as
+   described above.  This usually requires two variant definitions, of which
+   `REG_OK_STRICT' controls the one actually used.  */
+#define REG_OK_FOR_BASE_P(X) 1
+
+
+/* A C statement or compound statement with a conditional `goto LABEL;'
+   executed if memory address X (an RTX) can have different meanings depending
+   on the machine mode of the memory reference it is used for or if the address
+   is valid for some modes but not others.
+
+   Autoincrement and autodecrement addresses typically have mode-dependent
+   effects because the amount of the increment or decrement is the size of the
+   operand being addressed.  Some machines have other mode-dependent addresses.
+   Many RISC machines have no mode-dependent addresses.
+
+   You may assume that ADDR is a valid address for the machine.  */
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)
+
+
+/* An initializer that says which registers are used for fixed purposes all
+   throughout the compiled code and are therefore not available for general
+   allocation.  These would include the stack pointer, the frame pointer
+   (except on machines where that can be used as a general register when no
+   frame pointer is needed), the program counter on machines where that is
+   considered one of the addressable registers, and any other numbered register
+   with a standard use.
+
+   This information is expressed as a sequence of numbers, separated by commas
+   and surrounded by braces.  The Nth number is 1 if register N is fixed, 0
+   otherwise.
+
+   The table initialized from this macro, and the table initialized by the
+   following one, may be overridden at run time either automatically, by the
+   actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
+   command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'.  */
+#define FIXED_REGISTERS 			\
+  { 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+/* 256-511 */ \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+/* fp 512 - 767 */ \
+    1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+/* fp 768 - 1024 */ \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
+  }
+
+/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
+   general) by function calls as well as for fixed registers.  This macro
+   therefore identifies the registers that are not available for general
+   allocation of values that must live across function calls.
+
+   If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
+   saves it on function entry and restores it on function exit, if the register
+   is used within the function.  */
+#define CALL_USED_REGISTERS 			\
+  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+/* 256-511 */ \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+/* fp 512 - 767 */ \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+/* fp 768 - 1024 */ \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  \
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0  \
+  }
+
+/* An initializer containing the contents of the register classes, as integers
+   which are bit masks.  The Nth integer specifies the contents of class N.
+   The way the integer MASK is interpreted is that register R is in the class
+   if `MASK & (1 << R)' is 1.
+
+   When the machine has more than 32 registers, an integer does not suffice.
+   Then the integers are replaced by sub-initializers, braced groupings
+   containing several integers.  Each sub-initializer must be suitable as an
+   initializer for the type `HARD_REG_SET' which is defined in
+   `hard-reg-set.h'.  */
+#define REG_CLASS_CONTENTS  \
+{ 							\
+}
+
+/* A C initializer containing the assembler's names for the machine registers,
+   each one as a C string constant.  This is what translates register numbers
+   in the compiler into assembler language.  */
+#define REGISTER_NAMES 						\
+{   "rv", "sp", "iarg1",  "iarg2",  "iarg3",  "iarg4", "fp", "r7" } 
+
+/* An initializer containing the names of the register classes as C string
+   constants.  These names are used in writing some of the debugging dumps.  */
+#define REG_CLASS_NAMES \
+{			  \
+  "NO_REGS",  \
+  "INT_REGS", \
+  "FP_REGS",  \
+  "ALL_REGS"  \
+ }
+
+/* A C expression whose value is a string containing the assembler operation
+   that should precede instructions and read-only data.  Normally `".text"' is
+   right.  */
+#define TEXT_SECTION_ASM_OP "\t.text"
+
+/* A C expression whose value is a string containing the assembler operation to
+   identify the following data as writable initialized data.  Normally
+   `".data"' is right.  */
+#define DATA_SECTION_ASM_OP "\t.data"
+
+/* Globalizing directive for a label.  */
+#define GLOBAL_ASM_OP "\t.globl "
+
+/* A C expression which defines the machine-dependent operand constraint
+   letters for register classes.  If CHAR is such a letter, the value should be
+   the register class corresponding to it.  Otherwise, the value should be
+   `NO_REGS'.  The register letter `r', corresponding to class `GENERAL_REGS',
+   will not be passed to this macro; you do not need to handle it.
+
+   The following letters are unavailable, due to being used as
+   constraints:
+	'0'..'9'
+	'<', '>'
+	'E', 'F', 'G', 'H'
+	'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'
+	'Q', 'R', 'S', 'T', 'U'
+	'V', 'X'
+	'g', 'i', 'm', 'n', 'o', 'p', 'r', 's' */
+
+#define REG_CLASS_FROM_LETTER(CHAR) 	\
+     (  (CHAR) == 'r' ? INT_REGS	\
+      : (CHAR) == 'f' ? FP_REGS  \
+      : NO_REGS)
+
+
+/* An alias for the machine mode for pointers.  On most machines, define this
+   to be the integer mode corresponding to the width of a hardware pointer;
+   `SImode' on 32-bit machine or `DImode' on 64-bit machines.  On some machines
+   you must define this to be one of the partial integer modes, such as
+   `PSImode'.
+
+   The width of `Pmode' must be at least as large as the value of
+   `POINTER_SIZE'.  If it is not equal, you must define the macro
+   `POINTERS_EXTEND_UNSIGNED' to specify how pointers are extended to `Pmode'.  */
+#define Pmode SImode
+
+/* An alias for the machine mode used for memory references to functions being
+   called, in `call' RTL expressions.  On most machines this should be
+   `QImode'.  */
+#define FUNCTION_MODE SImode
+
+/* The maximum number of bytes that a single instruction can move quickly from
+   memory to memory.  */
+#define MOVE_MAX 4
+
+/* An alias for a machine mode name.  This is the machine mode that elements of
+   a jump-table should have.  */
+#define CASE_VECTOR_MODE SImode
+
+/* A C expression that should indicate the number of bytes of its own arguments
+   that a function pops on returning, or 0 if the function pops no arguments
+   and the caller must therefore pop them all after the function returns.
+
+   FUNDECL is a C variable whose value is a tree node that describes the
+   function in question.  Normally it is a node of type `FUNCTION_DECL' that
+   describes the declaration of the function.  From this it is possible to
+   obtain the DECL_ATTRIBUTES of the function.
+
+   FUNTYPE is a C variable whose value is a tree node that describes the
+   function in question.  Normally it is a node of type `FUNCTION_TYPE' that
+   describes the data type of the function.  From this it is possible to obtain
+   the data types of the value and arguments (if known).
+
+   When a call to a library function is being considered, FUNTYPE will contain
+   an identifier node for the library function.  Thus, if you need to
+   distinguish among various library functions, you can do so by their names.
+   Note that "library function" in this context means a function used to
+   perform arithmetic, whose name is known specially in the compiler and was
+   not mentioned in the C code being compiled.
+
+   STACK-SIZE is the number of bytes of arguments passed on the stack.  If a
+   variable number of bytes is passed, it is zero, and argument popping will
+   always be the responsibility of the calling function.
+
+   On the VAX, all functions always pop their arguments, so the definition of
+   this macro is STACK-SIZE.  On the 68000, using the standard calling
+   convention, no functions pop their arguments, so the value of the macro is
+   always 0 in this case.  But an alternative calling convention is available
+   in which functions that take a fixed number of arguments pop them but other
+   functions (such as `printf') pop nothing (the caller pops all).  When this
+   convention is in use, FUNTYPE is examined to determine whether a function
+   takes a fixed number of arguments.  */
+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
+
+/* A C statement (sans semicolon) for initializing the variable CUM for the
+   state at the beginning of the argument list.  The variable has type
+   `CUMULATIVE_ARGS'.  The value of FNTYPE is the tree node for the data type
+   of the function which will receive the args, or 0 if the args are to a
+   compiler support library function.  The value of INDIRECT is nonzero when
+   processing an indirect call, for example a call through a function pointer.
+   The value of INDIRECT is zero for a call to an explicitly named function, a
+   library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
+   arguments for the function being compiled.
+
+   When processing a call to a compiler support library function, LIBNAME
+   identifies which one.  It is a `symbol_ref' rtx which contains the name of
+   the function, as a string.  LIBNAME is 0 when an ordinary C function call is
+   being processed.  Thus, each time this macro is called, either LIBNAME or
+   FNTYPE is nonzero, but never both of them at once.  */
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
+  (CUM) = 0
+
+/* The number of register assigned to holding function arguments.  */
+     
+#define ARG_REGS	 4
+
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED)			\
+  (  (NAMED) == 0                    ? NULL_RTX			\
+   : targetm.calls.must_pass_in_stack (MODE, TYPE) ? NULL_RTX	\
+   : (CUM) >= ARG_REGS      ? NULL_RTX			\
+   : gen_rtx_REG (MODE, CUM + FIRST_ARG_REGNUM))
+
+/* A C statement (sans semicolon) to update the summarizer variable CUM to
+   advance past an argument in the argument list.  The values MODE, TYPE and
+   NAMED describe that argument.  Once this is done, the variable CUM is
+   suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
+
+   This macro need not do anything if the argument in question was passed on
+   the stack.  The compiler knows how to track the amount of stack space used
+   for arguments without any special help.  */
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) 
+
+/* A C expression which is nonzero if on this machine it is safe to "convert"
+   an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
+   than INPREC) by merely operating on it as if it had only OUTPREC bits.
+
+   On many machines, this expression can be 1.
+
+   When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
+   which `MODES_TIEABLE_P' is 0, suboptimal code can result.  If this is the
+   case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
+   things.  */
+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
+
+/*{{{  Assembler Commands for Alignment.  */ 
+
+/* A C statement to output to the stdio stream STREAM an assembler command to
+   advance the location counter to a multiple of 2 to the POWER bytes.  POWER
+   will be a C expression of type `int'.  */
+
+#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
+  fprintf ((STREAM), "\t.p2align %d\n", (POWER))
+
+/* A C expression that is 1 if the RTX X is a constant which is a valid
+   address.  On most machines, this can be defined as `CONSTANT_P (X)', but a
+   few machines are more restrictive in which constant addresses are supported.
+
+   `CONSTANT_P' accepts integer-values expressions whose values are not
+   explicitly known, such as `symbol_ref', `label_ref', and `high' expressions
+   and `const' arithmetic expressions, in addition to `const_int' and
+   `const_double' expressions.  */
+#define CONSTANT_ADDRESS_P(X) CONSTANT_P (X)
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+     gen_rtx_REG (TYPE_MODE (VALTYPE), RETURN_VALUE_REGNUM)
+
+/* A C expression to create an RTX representing the place where a library
+   function returns a value of mode MODE.  If the precise function being called
+   is known, FUNC is a tree node (`FUNCTION_DECL') for it; otherwise, FUNC is a
+   null pointer.  This makes it possible to use a different value-returning
+   convention for specific functions when all their calls are known.
+
+   Note that "library function" in this context means a compiler support
+   routine, used to perform arithmetic, whose name is known specially by the
+   compiler and was not mentioned in the C code being compiled.
+
+   The definition of `LIBRARY_VALUE' need not be concerned aggregate data
+   types, because none of the library functions returns such types.  */
+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, RETURN_VALUE_REGNUM)
+
+/* A C compound statement to output to stdio stream STREAM the assembler syntax
+   for an instruction operand X.  X is an RTL expression.
+
+   CODE is a value that can be used to specify one of several ways of printing
+   the operand.  It is used when identical operands must be printed differently
+   depending on the context.  CODE comes from the `%' specification that was
+   used to request printing of the operand.  If the specification was just
+   `%DIGIT' then CODE is 0; if the specification was `%LTR DIGIT' then CODE is
+   the ASCII code for LTR.
+
+   If X is a register, this macro should print the register's name.  The names
+   can be found in an array `reg_names' whose type is `char *[]'.  `reg_names'
+   is initialized from `REGISTER_NAMES'.
+
+   When the machine description has a specification `%PUNCT' (a `%' followed by
+   a punctuation character), this macro is called with a null pointer for X and
+   the punctuation character for CODE.  */
+#define PRINT_OPERAND(STREAM, X, CODE)
+
+
+/* A C compound statement to output to stdio stream STREAM the assembler syntax
+   for an instruction operand that is a memory reference whose address is X.  X
+   is an RTL expression.  */
+
+#define PRINT_OPERAND_ADDRESS(STREAM, X) 
+
+/* A C statement or compound statement to output to FILE some assembler code to
+   call the profiling subroutine `mcount'.  Before calling, the assembler code
+   must load the address of a counter variable into a register where `mcount'
+   expects to find the address.  The name of this variable is `LP' followed by
+   the number LABELNO, so you would generate the name using `LP%d' in a
+   `fprintf'.
+
+   The details of how the address should be passed to `mcount' are determined
+   by your operating system environment, not by GCC.  To figure them out,
+   compile a small program for profiling using the system's installed C
+   compiler and look at the assembler code that results.  */
+#define FUNCTION_PROFILER(FILE, LABELNO)	\
+{						\
+  fprintf (FILE, "\t mov rp, r1\n" );		\
+  fprintf (FILE, "\t ldi:32 mcount, r0\n" );	\
+  fprintf (FILE, "\t call @r0\n" );		\
+  fprintf (FILE, ".word\tLP%d\n", LABELNO);	\
+}
+
+/* Offset from the argument pointer register to the first argument's address.
+   On some machines it may depend on the data type of the function.
+
+   If `ARGS_GROW_DOWNWARD', this is the offset to the location above the first
+   argument's address.  */
+#define FIRST_PARM_OFFSET(FUNDECL) 0
+
+/* A C expression that is nonzero if it is desirable to choose register
+   allocation so as to avoid move instructions between a value of mode MODE1
+   and a value of mode MODE2.
+
+   If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
+   ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
+   zero.  */
+#define MODES_TIEABLE_P(MODE1, MODE2) 1
+
+/* A C expression that defines the machine-dependent operand constraint letters
+   (`I', `J', `K', .. 'P') that specify particular ranges of integer values.
+   If C is one of those letters, the expression should check that VALUE, an
+   integer, is in the appropriate range and return 1 if so, 0 otherwise.  If C
+   is not one of those letters, the value should be 0 regardless of VALUE.  */
+#define CONST_OK_FOR_LETTER_P(VALUE, C) 			\
+ (  (C) == 'I' ? IN_RANGE (VALUE,    0,       15)		\
+  : (C) == 'J' ? IN_RANGE (VALUE,  -16,       -1)		\
+  : (C) == 'K' ? IN_RANGE (VALUE,   16,       31)		\
+  : (C) == 'L' ? IN_RANGE (VALUE,    0,       (1 <<  8) - 1)	\
+  : (C) == 'M' ? IN_RANGE (VALUE,    0,       (1 << 20) - 1)	\
+  : (C) == 'P' ? IN_RANGE (VALUE,  -(1 << 8), (1 <<  8) - 1)	\
+  : 0)
+
+/* A C expression that defines the machine-dependent operand constraint letters
+   (`G', `H') that specify particular ranges of `const_double' values.
+
+   If C is one of those letters, the expression should check that VALUE, an RTX
+   of code `const_double', is in the appropriate range and return 1 if so, 0
+   otherwise.  If C is not one of those letters, the value should be 0
+   regardless of VALUE.
+
+   `const_double' is used for all floating-point constants and for `DImode'
+   fixed-point constants.  A given letter can accept either or both kinds of
+   values.  It can use `GET_MODE' to distinguish between these kinds.  */
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
+
+/* A C expression that places additional restrictions on the register class to
+   use when it is necessary to copy value X into a register in class CLASS.
+   The value is a register class; perhaps CLASS, or perhaps another, smaller
+   class.  On many machines, the following definition is safe:
+
+        #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
+
+   Sometimes returning a more restrictive class makes better code.  For
+   example, on the 68000, when X is an integer constant that is in range for a
+   `moveq' instruction, the value of this macro is always `DATA_REGS' as long
+   as CLASS includes the data registers.  Requiring a data register guarantees
+   that a `moveq' will be used.
+
+   If X is a `const_double', by returning `NO_REGS' you can force X into a
+   memory constant.  This is useful on certain machines where immediate
+   floating values cannot be loaded into certain kinds of registers.  */
+#define PREFERRED_RELOAD_CLASS(X, CLASS) CLASS
+
+/* A C expression for the maximum number of consecutive registers of
+   class CLASS needed to hold a value of mode MODE.
+
+   This is closely related to the macro `HARD_REGNO_NREGS'.  In fact, the value
+   of the macro `CLASS_MAX_NREGS (CLASS, MODE)' should be the maximum value of
+   `HARD_REGNO_NREGS (REGNO, MODE)' for all REGNO values in the class CLASS.
+
+   This macro helps control the handling of multiple-word values in
+   the reload pass.  */
+#define CLASS_MAX_NREGS(CLASS, MODE) HARD_REGNO_NREGS (0, MODE)
+
+/* A C expression for the number of consecutive hard registers, starting at
+   register number REGNO, required to hold a value of mode MODE.  */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) 			\
+  ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* A C expression which is nonzero if register number NUM is suitable for use
+   as a base register in operand addresses.  It may be either a suitable hard
+   register or a pseudo register that has been allocated such a hard register.  */
+#define REGNO_OK_FOR_BASE_P(NUM) 1
+
+/* A C expression which is nonzero if register number NUM is suitable for use
+   as an index register in operand addresses.  It may be either a suitable hard
+   register or a pseudo register that has been allocated such a hard register.
+
+   The difference between an index register and a base register is that the
+   index register may be scaled.  If an address involves the sum of two
+   registers, neither one of them scaled, then either one may be labeled the
+   "base" and the other the "index"; but whichever labeling is used must fit
+   the machine's constraints of which registers may serve in each capacity.
+   The compiler will try both labelings, looking for one that is valid, and
+   will reload one or both registers only if neither labeling works.  */
+#define REGNO_OK_FOR_INDEX_P(NUM) 1
+
+/* A C expression that is nonzero if REGNO is the number of a hard register in
+   which the values of called function may come back.  */
+#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == RETURN_VALUE_REGNUM)
+
+/* A C expression that is nonzero if X (assumed to be a `reg' RTX) is valid for
+   use as an index register.
+
+   The difference between an index register and a base register is that the
+   index register may be scaled.  If an address involves the sum of two
+   registers, neither one of them scaled, then either one may be labeled the
+   "base" and the other the "index"; but whichever labeling is used must fit
+   the machine's constraints of which registers may serve in each capacity.
+   The compiler will try both labelings, looking for one that is valid, and
+   will reload one or both registers only if neither labeling works.  */
+#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
+// LLVM LOCAL end - TCE target

Added: llvm-gcc-4.2/trunk/gcc/config/tce/tce.md
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/config/tce/tce.md?rev=71655&view=auto

==============================================================================
--- llvm-gcc-4.2/trunk/gcc/config/tce/tce.md (added)
+++ llvm-gcc-4.2/trunk/gcc/config/tce/tce.md Wed May 13 08:10:04 2009
@@ -0,0 +1,14 @@
+;; LLVM LOCAL begin - TCE target
+(define_insn "jump"
+  [(set (pc) (label_ref (match_operand 0 "" "")))]
+  ""
+  "*"
+)
+
+;; Indirect jump through a register
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand:SI 0 "" "r"))]
+  "GET_CODE (operands[0]) != MEM || GET_CODE (XEXP (operands[0], 0)) != PLUS"
+  ""
+)
+;; LLVM LOCAL end - TCE target





More information about the llvm-commits mailing list