aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Chamberlain <sac@pobox.com>2000-01-05 05:57:17 +0000
committerJeff Law <law@gcc.gnu.org>2000-01-04 22:57:17 -0700
commit1b992148d7a6a6b0fffd946131dd7cd6e6cc3958 (patch)
tree2a608261fe1d5fa5730177f61de1aa3915d6188f
parent67e1e279c3b40476b000d67dfbc649e1aa6bc3ae (diff)
downloadgcc-1b992148d7a6a6b0fffd946131dd7cd6e6cc3958.zip
gcc-1b992148d7a6a6b0fffd946131dd7cd6e6cc3958.tar.gz
gcc-1b992148d7a6a6b0fffd946131dd7cd6e6cc3958.tar.bz2
configure.in: Add pj target.
* configure.in: Add pj target. * configure: Regenerate. * config/pj: New directory. * config/pj/lib1funcs.S: New file. * config/pj/linux.h: New file. * config/pj/pj.c: New file. * config/pj/pj.md: New file. * config/pj/pjl.h: New file. * config/pj/t-pj: New file. * config/pj/xm-pj.h: New file From-SVN: r31225
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/pj/lib1funcs.S192
-rw-r--r--gcc/config/pj/linux.h36
-rw-r--r--gcc/config/pj/pj-protos.h46
-rw-r--r--gcc/config/pj/pj.c1279
-rw-r--r--gcc/config/pj/pj.h1333
-rw-r--r--gcc/config/pj/pj.md991
-rw-r--r--gcc/config/pj/pjl.h1
-rw-r--r--gcc/config/pj/t-pj9
-rw-r--r--gcc/config/pj/xm-pj.h39
-rwxr-xr-xgcc/configure189
-rw-r--r--gcc/configure.in13
12 files changed, 4053 insertions, 88 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5f622fa..6bde0bd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+Tue Jan 4 22:55:41 2000 Steve Chamberlain <sac@pobox.com>
+
+ * configure.in: Add pj target.
+ * configure: Regenerate.
+ * config/pj: New directory.
+ * config/pj/lib1funcs.S: New file.
+ * config/pj/linux.h: New file.
+ * config/pj/pj.c: New file.
+ * config/pj/pj.md: New file.
+ * config/pj/pjl.h: New file.
+ * config/pj/t-pj: New file.
+ * config/pj/xm-pj.h: New file
+
Tue Jan 4 22:30:16 2000 Jeffrey A Law (law@cygnus.com)
* toplev.c (rest_of_compilation): Run shorten-branches before
diff --git a/gcc/config/pj/lib1funcs.S b/gcc/config/pj/lib1funcs.S
new file mode 100644
index 0000000..8f50b81
--- /dev/null
+++ b/gcc/config/pj/lib1funcs.S
@@ -0,0 +1,192 @@
+! lib1funcs.S for picoJava.
+! Copyright (C) 2000 Free Software Foundation, Inc.
+!
+! This file 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.
+!
+! In addition to the permissions in the GNU General Public License, the
+! Free Software Foundation gives you unlimited permission to link the
+! compiled version of this file with other programs, and to distribute
+! those programs without any restriction coming from the use of this
+! file. (The General Public License restrictions do apply in other
+! respects; for example, they cover modification of the file, and
+! distribution when not linked into another program.)
+!
+! This file 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 this program; see the file COPYING. If not, write to
+! the Free Software Foundation, 59 Temple Place - Suite 330,
+! Boston, MA 02111-1307, USA.
+!
+! As a special exception, if you link this library with files
+! compiled with GCC to produce an executable, this does not cause
+! the resulting executable to be covered by the GNU General Public License.
+! This exception does not however invalidate any other reasons why
+! the executable file might be covered by the GNU General Public License.
+!
+
+
+#ifdef Lvhelper
+
+! The vhelper copies unnamed args in a varargs function from the
+! opstack onto the aggregate stack. It is a bit tricky since the
+! opstack does not exist in real memory, so can not have its address taken,
+! and since the opstack is being played with, there is nowhere to stick
+! the temporaries.
+
+ .globl __vhelper
+__vhelper:
+
+
+! incoming
+! vars-> named0
+! named1
+! ...
+! unnamed0
+! unnamed1
+! ...
+! pc
+! vars
+! #named
+! return pc
+
+ ! work out total size everything below the named args and
+ ! allocate that space on the aggregate stack + 3 extra words
+ ! for some temps.
+ ! g0 = old g0
+ ! g0+4 = vars
+ ! g0+8 = pc
+ ! g0+12 = last unnamed arg
+ ! ....
+
+ write_global1
+ write_global2
+
+ ! tos = #named args provided by callee.
+
+ ! move down the aggstack to make room for all the unnamed args
+ ! and the 12 bytes of extra stuff we have to pay attention to.
+ ! g0 = old_g0 - ((vars - optop) + named_bytes + 12) - stuff we just pushed
+
+ ! build new global0
+ read_global0
+ read_vars
+ read_optop
+ isub ! tos = vars - optop (# bytes in all args)
+ bipush 4
+ isub ! subtract out fudge for current stuff on stack.
+ read_global2
+ isub ! subtract out # words named.
+ isub
+
+ dup
+ dup
+ ! store old global0 in new global0 spot.
+
+ read_global0
+ swap
+ store_word
+
+ ! store new global0 value into global0
+ write_global0
+
+ ! work out address to stop copying, which is vars - #named args bytes
+ ! but since we will have pushed stuff onto the stack when the comparison
+ ! is made, adjust by the fudge factor.
+ read_vars
+ read_global2
+ bipush 12
+ iadd
+ isub
+
+ ! optop= finish, vars, pc, ...
+ ! now pop off args from the opstack and copy to aggstack till all done.
+ ! during the loop the opstack looks like
+ ! (optop_finish_addr) (destination_addr) (named_n) (named_n-1) ....
+ ! each iteration pops off one more element.
+
+
+again:
+ dup_x2
+ read_optop
+ if_icmpeq done
+ iconst_4
+ iadd
+ dup_x2
+ store_word
+ goto again
+
+done:
+ dup2_x1 ; pop2 ; pop !leave pointer on top.
+
+ ! return to caller with varargs pointer as
+ ! the next argument and the restoring global0 as the next.
+
+ read_global0 ; load_word
+
+ ! restore returning pc and vars
+ read_global0 ; bipush 8; iadd; load_word
+ read_global0 ; bipush 4; iadd; load_word
+
+ ! return to caller.
+ read_global1
+ write_pc
+#endif
+
+
+#ifdef __LITTLE_ENDIAN__
+#define AL iload_1
+#define AH iload_0
+#define BL iload_3
+#define BH iload_2
+#else
+#define AL iload_0
+#define AH iload_1
+#define BL iload_2
+#define BH iload_3
+#endif
+#ifdef Lpjucmpdi2
+
+! like ucmpdi2, but returns <0,0,>0 depending on comparison input.
+! and returns answer on the stack, not in global1. - much like an
+! actual lucmp instruction would do if there was one.
+! big little
+!
+! vars-> 0 a low high
+! 1 a high low
+! 2 b low high
+! 3 b high low
+!
+! compares a to b
+! a > b return 1
+! a = b return 0
+! a < b return -1
+
+ .globl __pjucmpdi2
+__pjucmpdi2:
+
+! first see if we can compare the numbers using
+! the signed instruction.
+
+ AH
+ BH
+ if_icmpne high_words_diff
+ AL
+ BL
+ iucmp
+ return1
+
+! and low word if high word is equal.
+
+high_words_diff:
+ AH
+ BH
+ iucmp
+ return1
+#endif
diff --git a/gcc/config/pj/linux.h b/gcc/config/pj/linux.h
new file mode 100644
index 0000000..41d275e
--- /dev/null
+++ b/gcc/config/pj/linux.h
@@ -0,0 +1,36 @@
+/* Definitions for a picoJava Linux-based GNU system.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* contributed by Steve Chamberlain, of Transmeta. sac@pobox.com. */
+
+#define TARGET_LITTLE_ENDIAN_DEFAULT 1
+
+#undef CPP_PREDEFINES
+#undef STARTFILE_SPEC
+#undef ENDFILE_SPEC
+
+#define CPP_PREDEFINES "-D__ELF__ -Dunix -D__pj__ -Dlinux -Asystem(posix)"
+#define STARTFILE_SPEC "crt1.o%s crti.o%s crtbegin.o%s"
+#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
+
+#undef WCHAR_TYPE_SIZE
+#undef WCHAR_TYPE
+#define WCHAR_TYPE "long int"
+#define WCHAR_TYPE_SIZE BITS_PER_WORD
diff --git a/gcc/config/pj/pj-protos.h b/gcc/config/pj/pj-protos.h
new file mode 100644
index 0000000..d26df65
--- /dev/null
+++ b/gcc/config/pj/pj-protos.h
@@ -0,0 +1,46 @@
+/* Prototypes for pj.c functions used in the md file & elsewhere.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+void pj_expand_prologue PARAMS ((void));
+void pj_expand_epilogue PARAMS ((void));
+void pj_asm_output_opcode PARAMS ((FILE *, const char *));
+
+#ifdef RTX_CODE
+extern rtx pj_cmp_op0;
+extern rtx pj_cmp_op1;
+extern enum machine_mode pj_cmp_mode;
+extern int pj_stuff_on_line;
+extern const char *pj_standard_float_constant PARAMS ((rtx));
+extern int pj_source_operand PARAMS ((rtx op, enum machine_mode mode));
+extern int pj_signed_comparison_operator PARAMS ((rtx, enum machine_mode));
+extern int pj_unsigned_comparison_operator PARAMS ((rtx, enum machine_mode));
+extern rtx pj_workout_arg_words PARAMS ((rtx, rtx));
+extern void pj_machine_dependent_reorg PARAMS ((rtx));
+extern void pj_print_operand PARAMS ((FILE * stream, rtx x, int code));
+extern char *pj_output_addsi3 PARAMS ((rtx * operands));
+
+#ifdef TREE_CODE
+extern rtx pj_expand_builtin_va_arg PARAMS ((tree valist, tree type));
+extern rtx pj_function_incoming_arg PARAMS ((CUMULATIVE_ARGS * args_so_far,
+ enum machine_mode promote_mode,
+ tree passed_type,
+ int named_arg));
+#endif
+#endif
diff --git a/gcc/config/pj/pj.c b/gcc/config/pj/pj.c
new file mode 100644
index 0000000..ce83803
--- /dev/null
+++ b/gcc/config/pj/pj.c
@@ -0,0 +1,1279 @@
+/* Output routines for GCC for picoJava II
+ Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Contributed by Steve Chamberlain (sac@pobox.com), of Transmeta. */
+
+/* The picoJava architecture doesn't have general registers, it has an
+ operand stack. Any of the first 256 words on the operand stack between
+ the locations indicated by the vars register and the optop register
+ are accessible with one instruction, almost as if they were registers.
+ The opstack isn't aliased into memory, so deferecencing address of
+ something on the opstack is impossible.
+
+ Small scalar incoming arguments to a function arrive on the operand
+ stack, large scalars and aggregates arrive in the `aggregate'
+ stack. The aggregate stack lives in normal memory.
+
+
+ just before a call after the call insn and frame setup.
+
+ vars-> ....
+
+ arg-5 vars->arg-5
+ arg-4 arg-4
+ arg-3 arg-3
+ arg-2 arg-2
+ arg-1 arg-1
+ arg-0 arg-0
+ target-addr old-vars
+ #arg words old-pc
+ optop-> saved globals
+ local-0
+ local-1
+ ....
+ optop->
+
+ This port generates code for a machine with 32 general purpose
+ registers, and on output changes the references to the fake registers
+ into offsets from the vars register. Because the opstack grows
+ downwards and all indexes are negated, some care has to be taken here
+ to deal with endian problems; for example after a call on a little endian
+ machine, an incoming DImode argument of value 0x1122334455667788 in
+ `register 0', would live on the opstack like this:
+
+ vars - 0 0x11223344
+ vars - 4 0x55667788
+ vars - 8 old-vars
+ vars - 12 old-pc
+
+ The picoJava instructon to read and put that onto the opstack as a
+ DImode value is `lload 0', yet the least significant word lives at
+ vars - 4, for which the instruction is `iload 1'. The incoming
+ argument code remembers which arguments arrive swapped in the
+ CUMULATIVE_ARGS structure. The information is used to fill in
+ pj_si_vars_offset_vec and pj_di_vars_offset_vec during the prologue
+ printing.
+
+ Outgoing arguments are collected in fake `outgoing' registers, or
+ in the aggregate stack. The emitted code to write into an outgoing
+ register does nothing, which leaves the expression to be written on
+ the top of the opstack. GCC always evaluates arguments in the right
+ order, so nothing more needs to be done. */
+
+
+#include <setjmp.h>
+#include "config.h"
+#include "system.h"
+#include "rtl.h"
+#include "tree.h"
+#include "tm_p.h"
+#include "regs.h"
+#include "hard-reg-set.h"
+#include "real.h"
+#include "insn-config.h"
+#include "conditions.h"
+#include "insn-flags.h"
+#include "output.h"
+#include "insn-attr.h"
+#include "flags.h"
+#include "except.h"
+#include "function.h"
+#include "recog.h"
+#include "expr.h"
+#include "toplev.h"
+#include "basic-block.h"
+#include "ggc.h"
+
+/* Compare insns in pj.md store the information needed to generate
+ branch instructions here. */
+rtx pj_cmp_op0;
+rtx pj_cmp_op1;
+enum machine_mode pj_cmp_mode;
+
+static void pj_output_rval PROTO ((rtx, enum machine_mode, rtx));
+static void pj_output_store_into_lval PROTO ((enum machine_mode mode, rtx op));
+
+/* These vectors turn a register number into an offset from the vars
+ pointer register. */
+short pj_si_vars_offset_vec[FIRST_PSEUDO_REGISTER];
+short pj_di_vars_offset_vec[FIRST_PSEUDO_REGISTER];
+short pj_debugreg_renumber_vec[FIRST_PSEUDO_REGISTER];
+
+/* Number of fake registers in the frame, used by prologue and epilogue
+ code. */
+static int nfakes;
+
+/* Whether anything has been printed to the current assembly output
+ line. */
+int pj_stuff_on_line;
+
+/* printf to the asm_out_file, with special format control characters
+ for decoding operands.
+
+ %* - start of opcode
+ %d,%x,%c,%s - as printf
+ %X - address constant.
+ %<alpha><digit> - operand <digit> passed to pj_print_operand with code <alpha>. */
+
+static void pj_printf
+VPROTO ((const char *template, ...))
+{
+#ifndef ANSI_PROTOTYPES
+ const char *template;
+#endif
+ register int c;
+
+ va_list argptr;
+ int ops_read = 0;
+ rtx operands[10];
+ VA_START (argptr, template);
+#ifndef ANSI_PROTOTYPES
+ template = va_arg (argptr, const char *);
+#endif
+
+ while ((c = *template++))
+ {
+ int was_stuff_on_line = pj_stuff_on_line;
+ pj_stuff_on_line = 1;
+ switch (c)
+ {
+ case '\n':
+ putc (c, asm_out_file);
+ pj_stuff_on_line = 0;
+ break;
+ default:
+ putc (c, asm_out_file);
+ break;
+ case '%':
+ {
+ switch (*template)
+ {
+ case '%':
+ putc ('%', asm_out_file);
+ template++;
+ pj_stuff_on_line = 1;
+ break;
+ case '*':
+ /* Marks start of opcode, tab out. */
+ if (was_stuff_on_line)
+ fprintf (asm_out_file, "; ");
+ template++;
+ break;
+ case 'd':
+ template++;
+ fprintf (asm_out_file, "%d", va_arg (argptr, int));
+ break;
+ case 'x':
+ template++;
+ fprintf (asm_out_file, "%x", va_arg (argptr, int));
+ break;
+ case 'c':
+ template++;
+ fprintf (asm_out_file, "%c", va_arg (argptr, int));
+ break;
+ case 's':
+ template++;
+ fputs (va_arg (argptr, const char *), asm_out_file);
+ break;
+ case 'X':
+ template++;
+ output_addr_const (asm_out_file, va_arg (argptr, rtx));
+ break;
+ default:
+ {
+ int code = 0;
+ rtx send;
+
+ if (ISALPHA (*template))
+ code = *template++;
+ if (ISDIGIT (*template))
+ {
+ int num = atoi (template);
+ template++;
+ while (ops_read <= num)
+ operands[ops_read++] = va_arg (argptr, rtx);
+ send = operands[num];
+ }
+ else
+ send = va_arg (argptr, rtx);
+
+ /* A null means leave the word on the stack, so there's
+ no need to do anything for that. */
+
+ if (send)
+ pj_print_operand (asm_out_file, send, code);
+ }
+ }
+ }
+ }
+ }
+ va_end (argptr);
+}
+
+/* Output code to efficiently push a single word integer constant onto
+ the opstack. */
+
+static void
+pj_output_push_int (val)
+ int val;
+{
+ int low = ((val & 0x8000) ? ~0xffff : 0) | (val & 0xffff);
+
+ if (low == -1)
+ pj_printf ("%*iconst_m1");
+ else if (low >= 0 && low <= 5)
+ pj_printf ("%*iconst_%d", low);
+ else if (low >= -128 && low < 128)
+ pj_printf ("%*bipush %d", low);
+ else
+ pj_printf ("%*sipush %d", low);
+
+ if ((low & 0xffff0000) != (val & 0xffff0000))
+ pj_printf ("%*sethi 0x%x", (val >> 16) & 0xffff);
+}
+
+/* Output code to add a constant to the value on the top of the
+ opstack. */
+
+static void
+pj_output_print_add_k (int size)
+{
+ if (size >= 0)
+ {
+ pj_output_push_int (size);
+ pj_printf ("%*iadd");
+ }
+ else
+ {
+ pj_output_push_int (-size);
+ pj_printf ("%*isub");
+ }
+}
+
+/* Output code to load the value pointed to by the top of stack onto
+ the stack. */
+
+static void
+pj_output_load (mode, uns)
+ enum machine_mode mode;
+ int uns;
+{
+ int i;
+ switch (GET_MODE_SIZE (mode))
+ {
+ case 1:
+ pj_printf (uns ? "%*load_ubyte" : "%*load_byte");
+ break;
+ case 2:
+ pj_printf (uns ? "%*load_char" : "%*load_short");
+ break;
+ case 8:
+ if (TARGET_TM_EXTENSIONS)
+ {
+ pj_printf ("%*tm_load_long");
+ break;
+ }
+ /* Fall through. */
+ default:
+ for (i = GET_MODE_SIZE (mode); i > 4; i -= 4)
+ {
+ pj_printf ("%*dup");
+ pj_output_print_add_k (i - 4);
+ pj_printf ("%*load_word");
+ pj_printf ("%*swap");
+ }
+ pj_printf ("%*load_word");
+ }
+}
+
+/* Output code to increment the provided lval operand. */
+
+static void
+pj_output_inc (op, size)
+ rtx op;
+ int size;
+{
+ if (STACK_REG_RTX_P (op))
+ pj_printf ("%*iinc %d,%d", pj_si_vars_offset_vec[REGNO (op)], size);
+ else
+ {
+ pj_output_rval (op, SImode, 0);
+ pj_output_push_int (size);
+ pj_printf ("%*iadd");
+ pj_output_store_into_lval (SImode, op);
+ }
+}
+
+/* Output the text for a conversion operator. */
+
+static void
+pj_output_cnv_op (e, op)
+ enum insn_code e;
+ rtx op;
+{
+ pj_printf ((const char *) insn_data[(int) e].output, 0, XEXP (op, 0));
+}
+
+/* Turn a machine_mode into an opcode modifier chararacter. */
+
+static char
+mode_to_char (mode)
+ enum machine_mode mode;
+{
+ switch (mode)
+ {
+ case QImode:
+ case HImode:
+ case SImode:
+ return 'i';
+ break;
+ case DImode:
+ return 'l';
+ break;
+ case DFmode:
+ return 'd';
+ break;
+ case SFmode:
+ return 'f';
+ break;
+ default:
+ abort ();
+ }
+}
+
+/* Output an index off the var register. If we're moving an 8 byte
+ value then reduce the index, since the picoJava instruction loading
+ the value uses the index of the highest part of the register as
+ it's name. */
+
+static void
+pj_output_varidx (mode, do_store, idx)
+ enum machine_mode mode;
+ int do_store;
+ int idx;
+{
+ pj_printf ("%*%c%s%c%d",
+ mode_to_char (mode),
+ do_store ? "store" : "load",
+ (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
+ && idx <= 3 ? '_' : ' ', idx);
+}
+
+/* Output an rvalue expression. */
+
+static void
+pj_output_rval (op, mode, outer_op)
+ rtx op;
+ enum machine_mode mode;
+ rtx outer_op;
+{
+ enum rtx_code code = GET_CODE (op);
+
+ optab tab;
+
+ if (code == DIV && GET_MODE_CLASS (mode) == MODE_INT)
+ tab = sdiv_optab;
+ else
+ tab = code_to_optab[code];
+
+ if (code == PLUS)
+ {
+ pj_output_rval (XEXP (op, 0), mode, op);
+ pj_output_rval (XEXP (op, 1), mode, op);
+ pj_printf ("%*%cadd", mode_to_char (mode));
+ }
+ else if (tab && tab->handlers[mode].insn_code != CODE_FOR_nothing)
+ {
+ const char *template =
+ (const char *) insn_data[tab->handlers[mode].insn_code].output;
+ if (code == NEG)
+ pj_printf (template, 0, XEXP (op, 0));
+ else
+ pj_printf (template, 0, XEXP (op, 0), XEXP (op, 1));
+ }
+ else
+ switch (GET_CODE (op))
+ {
+ case PC:
+ fprintf (asm_out_file, " pc ");
+ break;
+
+ case CONST:
+ pj_output_rval (XEXP (op, 0), mode, op);
+ break;
+
+ case MEM:
+ pj_output_rval (XEXP (op, 0), Pmode, op);
+ pj_output_load (mode, 0);
+ break;
+
+ case SYMBOL_REF:
+ pj_printf ("%*ipush %X", op);
+ break;
+
+ case REG:
+ switch (mode)
+ {
+ case SImode:
+ case SFmode:
+ case HImode:
+ case QImode:
+ if (pj_si_vars_offset_vec[REGNO (op)] >= 0)
+ pj_output_varidx (mode, 0, pj_si_vars_offset_vec[REGNO (op)]);
+ else
+ pj_printf ("%*read_%s", reg_names[REGNO (op)]);
+ break;
+ case DImode:
+ case DFmode:
+ if (pj_di_vars_offset_vec[REGNO (op)] >= 0)
+ pj_output_varidx (mode, 0, pj_di_vars_offset_vec[REGNO (op)]);
+ else
+ switch (REGNO (op))
+ {
+ case G1_REG:
+ pj_printf ("%*read_global2");
+ pj_printf ("%*read_global1");
+ break;
+
+ /* A 64 bit read of global0 gives global0 and
+ optop. */
+ case G0_REG:
+ pj_printf ("%*read_optop");
+ pj_printf ("%*read_global0");
+ break;
+
+ default:
+ abort ();
+ }
+ break;
+ default:
+ abort ();
+ }
+ break;
+
+ case CONST_DOUBLE:
+ pj_printf (pj_standard_float_constant (op));
+ break;
+
+ case CONST_INT:
+ if (mode == SImode || mode == HImode || mode == QImode)
+ pj_output_push_int (INTVAL (op));
+ else if (mode == DImode)
+ {
+ int v = INTVAL (op);
+ if (v == 1)
+ pj_printf ("%*lconst_1", 0);
+ else if (v == 0)
+ pj_printf ("%*lconst_0", 0);
+ else
+ {
+ rtx hi = GEN_INT (v < 0 ? -1 : 0);
+ rtx lo = op;
+ pj_output_rval (TARGET_LITTLE_ENDIAN ? hi : lo, SImode, op);
+ pj_output_rval (TARGET_LITTLE_ENDIAN ? lo : hi, SImode, op);
+ }
+ }
+ else
+ abort ();
+ break;
+
+ case FLOAT_TRUNCATE:
+ pj_printf ("%S0%*d2f", XEXP (op, 0));
+ break;
+ case LABEL_REF:
+ pj_printf ("%*ipush %X", XEXP (op, 0));
+ break;
+
+ case SUBREG:
+ pj_output_rval (alter_subreg (op), mode, outer_op);
+ break;
+
+ case POST_INC:
+ pj_output_rval (XEXP (op, 0), mode, op);
+ pj_output_inc (XEXP (op, 0), GET_MODE_SIZE (GET_MODE (outer_op)));
+ break;
+
+ case POST_DEC:
+ pj_output_rval (XEXP (op, 0), mode, op);
+ pj_output_inc (XEXP (op, 0), -GET_MODE_SIZE (GET_MODE (outer_op)));
+ break;
+
+ case PRE_INC:
+ pj_output_inc (XEXP (op, 0), GET_MODE_SIZE (GET_MODE (outer_op)));
+ pj_output_rval (XEXP (op, 0), mode, op);
+ break;
+
+ case PRE_DEC:
+ if (OPTOP_REG_RTX_P (XEXP (op, 0)))
+ pj_output_rval (XEXP (op, 0), mode, op);
+ else if (STACK_REG_RTX_P (XEXP (op, 0)))
+ {
+ pj_output_inc (XEXP (op, 0),
+ -GET_MODE_SIZE (GET_MODE (outer_op)));
+ pj_output_rval (XEXP (op, 0), mode, op);
+ }
+ else
+ {
+ pj_printf ("%S0", XEXP (op, 0));
+ pj_output_print_add_k (-GET_MODE_SIZE (GET_MODE (outer_op)));
+ pj_printf ("%*dup%R0", XEXP (op, 0));
+ }
+ break;
+
+ case FIX:
+ pj_output_cnv_op (fixtrunctab[GET_MODE (XEXP (op, 0))][mode][0], op);
+ break;
+
+ case FLOAT:
+ if (mode == DFmode && GET_CODE (XEXP (op, 0)) == CONST_INT)
+ pj_output_cnv_op (floattab[mode][SImode][0], op);
+ else
+ pj_output_cnv_op (floattab[mode][GET_MODE (XEXP (op, 0))][0], op);
+ break;
+
+ case FLOAT_EXTEND:
+ case SIGN_EXTEND:
+ /* Sign extending from a memop to register is automatic. */
+ if (mode == SImode && GET_CODE (XEXP (op, 0)) == MEM)
+ pj_output_rval (XEXP (op, 0), GET_MODE (XEXP (op, 0)), op);
+ else
+ pj_output_cnv_op (extendtab[mode][GET_MODE (XEXP (op, 0))][0], op);
+ break;
+
+ case ZERO_EXTEND:
+ pj_output_cnv_op (extendtab[mode][GET_MODE (XEXP (op, 0))][1], op);
+ break;
+
+ default:
+ abort ();
+ break;
+ }
+}
+
+/* Store the top of stack into the lval operand OP. */
+
+void
+pj_output_store_into_lval (mode, op)
+ enum machine_mode mode;
+ rtx op;
+{
+ if (GET_CODE (op) == REG)
+ {
+ int rn = REGNO (op);
+
+ /* Outgoing values are left on the stack and not written
+ anywhere. */
+ if (!OUTGOING_REG_RTX_P (op))
+ {
+ switch (GET_MODE (op))
+ {
+ case SImode:
+ case QImode:
+ case HImode:
+ case SFmode:
+ if (pj_si_vars_offset_vec[rn] >= 0)
+ pj_output_varidx (mode, 1, pj_si_vars_offset_vec[rn]);
+ else
+ pj_printf ("%*write_%s", reg_names[rn]);
+ break;
+ case DImode:
+ case DFmode:
+ if (pj_di_vars_offset_vec[rn] >= 0)
+ pj_output_varidx (mode, 1, pj_di_vars_offset_vec[rn]);
+ else
+ switch (rn)
+ {
+ case G1_REG:
+ pj_printf ("%*write_global1");
+ pj_printf ("%*write_global2");
+ break;
+ default:
+ abort ();
+ }
+ break;
+ default:
+ abort ();
+ }
+ }
+ }
+ else
+ {
+ pj_output_rval (XEXP (op, 0), Pmode, op);
+
+ switch (GET_MODE_SIZE (mode))
+ {
+ case 1:
+ pj_printf ("%*store_byte", 0);
+ break;
+ case 2:
+ pj_printf ("%*store_short", 0);
+ break;
+ case 8:
+ if (TARGET_TM_EXTENSIONS)
+ {
+ pj_printf ("%*tm_store_long");
+ break;
+ }
+ /* Fall through. */
+ default:
+ {
+ int i;
+ for (i = GET_MODE_SIZE (mode); i > 4; i -= 4)
+ {
+ pj_printf ("%*dup_x1", 0);
+ pj_printf ("%*store_word", 0);
+ pj_printf ("%*iconst_4", 0);
+ pj_printf ("%*iadd", 0);
+ }
+ }
+ pj_printf ("%*store_word", 0);
+ break;
+ }
+ }
+}
+
+/* Print a condition, unsigned and signed have the same text because
+ the unsigned operands have been run through icmp first. */
+
+static void
+pj_print_cond (code)
+ enum rtx_code code;
+{
+ switch (code)
+ {
+ case EQ:
+ fputs ("eq", asm_out_file);
+ break;
+ case NE:
+ fputs ("ne", asm_out_file);
+ break;
+ case GT:
+ case GTU:
+ fputs ("gt", asm_out_file);
+ break;
+ case GE:
+ case GEU:
+ fputs ("ge", asm_out_file);
+ break;
+ case LT:
+ case LTU:
+ fputs ("lt", asm_out_file);
+ break;
+ case LE:
+ case LEU:
+ fputs ("le", asm_out_file);
+ break;
+ default:
+ abort ();
+ }
+}
+/* Print operand X (an rtx) in assembler syntax to file STREAM
+ according to modifier CODE.
+
+ C emit the first part of a Check_call pseudop.
+ D emit operand, if no mode, assume DImode.
+ E emit the second part of a check_call pseudop.
+ I print the XEXP (X, 0) Inside of the operand.
+ J print Just the integer or register part of an operand, for iinc.
+ P emit source is SI padded to DI with 0, used for unsigned mod and divide.
+ R emit the operand as an lval Result.
+ S emit Source operand, if no mode, assume SImode.
+ X nan choice suffix for floating point comparision.
+ Y condition name from op.
+ Z Y, reversed.
+ * marks start of opcode. */
+
+void
+pj_print_operand (stream, x, code)
+ FILE *stream;
+ rtx x;
+ int code;
+{
+ static int last_call_known;
+ switch (code)
+ {
+ case 'C':
+ if (GET_CODE (x) == SYMBOL_REF)
+ {
+ last_call_known = 1;
+ pj_printf ("%*.check_call %0", x);
+ }
+ else
+ last_call_known = 0;
+ break;
+
+ case 'D':
+ pj_output_rval (x,
+ GET_MODE (x) == VOIDmode ? DImode : GET_MODE (x),
+ NULL_RTX);
+ break;
+
+ case 'E':
+ if (last_call_known)
+ pj_printf (",%d", INTVAL (x));
+ break;
+
+ case 'I':
+ pj_output_rval (XEXP (x, 0), GET_MODE (XEXP (x, 0)), NULL_RTX);
+ break;
+
+ case 'J':
+ if (GET_CODE (x) == CONST_INT)
+ pj_printf ("%d", INTVAL (x));
+ else if (GET_CODE (x) == REG)
+ pj_printf ("%d", pj_si_vars_offset_vec[REGNO (x)]);
+ else
+ abort ();
+ break;
+
+ case 'P':
+ if (TARGET_LITTLE_ENDIAN)
+ pj_printf ("%*iconst_0", 0);
+ pj_output_rval (x,
+ GET_MODE (x) == VOIDmode ? SImode : GET_MODE (x),
+ NULL_RTX);
+ if (!TARGET_LITTLE_ENDIAN)
+ pj_printf ("%*iconst_0", 0);
+ break;
+
+ case 'R':
+ pj_output_store_into_lval (GET_MODE (x), x);
+ break;
+
+ case 'S':
+ pj_output_rval (x,
+ GET_MODE (x) == VOIDmode ? SImode : GET_MODE (x),
+ NULL_RTX);
+ break;
+
+ case 'X':
+ fputc (GET_CODE (x) == LT || GET_CODE (x) == LE ? 'g' : 'l', stream);
+ break;
+
+ case 'Y':
+ pj_print_cond (GET_CODE (x));
+ break;
+
+ case 'Z':
+ pj_print_cond (reverse_condition (GET_CODE (x)));
+ break;
+
+ case '*':
+ pj_printf ("%*");
+ break;
+
+ default:
+ output_addr_const (stream, x);
+ break;
+ }
+}
+
+/* Return in an rtx the number of words pushed onto the optop to be
+ used as the word count in a call insn. (NEXT_ARG_REG is NULL when
+ called from expand_builtin_apply). */
+
+rtx
+pj_workout_arg_words (stack_size, next_arg_reg)
+ rtx stack_size ATTRIBUTE_UNUSED;
+ rtx next_arg_reg;
+{
+ return GEN_INT ((next_arg_reg ? REGNO (next_arg_reg) - O0_REG : 0) + 2);
+}
+
+/* Handle the INCOMING_FUNCTION_ARG macro.
+ Determine where to put an argument to a function.
+ Value is zero to push the argument on the stack,
+ or a hard register in which to store the argument.
+
+ CUM is a variable of type CUMULATIVE_ARGS which gives info about
+ the preceding args and about the function being called.
+ MODE is the argument's machine mode.
+ TYPE is the data type of the argument (as a tree).
+ This is null for libcalls where that information may
+ not be available.
+ NAMED is nonzero if this argument is a named parameter
+ (otherwise it is an extra parameter matching an ellipsis). */
+
+rtx
+pj_function_incoming_arg (cum, mode, passed_type, named_arg)
+ CUMULATIVE_ARGS *cum;
+ enum machine_mode mode;
+ tree passed_type ATTRIBUTE_UNUSED;
+ int named_arg ATTRIBUTE_UNUSED;
+{
+ int arg_words = PJ_ARG_WORDS (mode);
+
+ /* If the whole argument will fit into registers, return the first
+ register needed. Also fill in the arg_adjust information so that
+ we can work out the right offset to use when looking at the
+ insides of a DI or DF value. */
+
+ if (cum->total_words + arg_words <= ARGS_IN_REGS)
+ {
+ int i;
+ if (mode == DImode || mode == DFmode)
+ {
+ cum->arg_adjust[cum->total_words + 0] = +1;
+ cum->arg_adjust[cum->total_words + 1] = -1;
+ }
+ else
+ for (i = 0; i < arg_words; i++)
+ cum->arg_adjust[cum->total_words + i] = 0;
+
+ return gen_rtx (REG, mode, I0_REG + cum->total_words);
+ }
+ return NULL_RTX;
+}
+
+/* Output code to add two SImode values. Deals carefully with the the common
+ case of moving the optop. */
+
+char *
+pj_output_addsi3 (operands)
+ rtx *operands;
+{
+ if (OPTOP_REG_RTX_P (operands[0]) && OPTOP_REG_RTX_P (operands[1])
+ && GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) >= -32 && INTVAL (operands[2]) <= 32)
+ {
+ static struct
+ {
+ const char *two;
+ const char *one;
+ }
+ name[2] =
+ {
+ { "pop2", "pop"},
+ { "lconst_0", "iconst_0"}
+ };
+ int size = INTVAL (operands[2]);
+ int d = 0;
+
+ if (size < 0)
+ {
+ d = 1;
+ size = -size;
+ }
+
+ for (; size >= 8; size -= 8)
+ output_asm_insn (name[d].two, 0);
+
+
+ if (size > 0)
+ output_asm_insn (name[d].one, 0);
+
+ return "";
+ }
+
+ if (STACK_REG_RTX_P (operands[0])
+ && rtx_equal_p (operands[0], operands[1])
+ && GET_CODE (operands[2]) == CONST_INT
+ && INTVAL (operands[2]) >= -128 && INTVAL (operands[2]) <= 127)
+ {
+ return "iinc %J0,%J2";
+ }
+
+ return "%S1%S2%*iadd%R0";
+}
+
+/* Generate rtl for the prologue of the current function. */
+
+void
+pj_expand_prologue ()
+{
+ int i;
+ int off = 0;
+ int arg_words = current_function->args_info.named_words;
+
+ memset (pj_si_vars_offset_vec, -1, sizeof (pj_si_vars_offset_vec));
+ memset (pj_di_vars_offset_vec, -1, sizeof (pj_di_vars_offset_vec));
+
+ /* Work out the register numbers of the named arguments. */
+ for (i = 0; i < current_function->args_info.named_words; i++)
+ {
+ pj_debugreg_renumber_vec[I0_REG + i]
+ = off + R0_REG + current_function->args_info.arg_adjust[i];
+ pj_si_vars_offset_vec[I0_REG + i]
+ = off + current_function->args_info.arg_adjust[i];
+ pj_di_vars_offset_vec[I0_REG + i] = off;
+ off++;
+ }
+
+ if (current_function_varargs || current_function_stdarg)
+ {
+ /* If the function is varadic we need to call the vhelper
+ function. vhelper pops off the unnamed argument words from
+ the opstack and puts them onto the the aggregate stack. The
+ unnamed words are replacedwith two extra arguments, a pointer
+ to the aggreagate stack for the first vararg and the original
+ global0 value. */
+
+ emit_insn (gen_varargs (GEN_INT (arg_words * 4)));
+ pj_si_vars_offset_vec[VA_REG] = off++;
+ off++;
+ arg_words += 2;
+ }
+
+ /* Skip over the return pc and old vars in the frame. */
+ off += 2;
+
+ /* Work out the register numbers and offsets from the var pointer
+ for the normal registers. */
+ nfakes = 0;
+
+ for (i = LAST_I_REG; i >= R0_REG; i--)
+ if (regs_ever_live[i] && pj_si_vars_offset_vec[i] == -1)
+ {
+ nfakes++;
+ pj_si_vars_offset_vec[i] = off;
+ pj_di_vars_offset_vec[i] = off - 1;
+ pj_debugreg_renumber_vec[i] = off + R0_REG;
+ off++;
+ }
+
+ if (TARGET_TEST)
+ {
+ fprintf (asm_out_file, "\n\t! args %d, size %d, fakes %d\n",
+ arg_words,
+ get_frame_size () / 4,
+ nfakes);
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (pj_si_vars_offset_vec[i] >= 0)
+ fprintf (asm_out_file, "\t!vars - %d %d: %s\n",
+ pj_si_vars_offset_vec[i],
+ pj_di_vars_offset_vec[i],
+ reg_names[i]);
+ }
+
+ /* Make room on the opstack for the fake registers. */
+ if (TARGET_TM_EXTENSIONS)
+ RTX_FRAME_RELATED_P (emit_insn (gen_tm_frame (GEN_INT (arg_words),
+ GEN_INT (nfakes)))) = 1;
+ else
+ RTX_FRAME_RELATED_P (emit_insn
+ (gen_addsi3
+ (gen_rtx_REG (SImode, OPTOP_REG),
+ gen_rtx_REG (SImode, OPTOP_REG),
+ GEN_INT (-nfakes * 4)))) = 1;
+
+
+ if (frame_pointer_needed)
+ emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
+
+ if (get_frame_size ())
+ RTX_FRAME_RELATED_P (emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx,
+ GEN_INT
+ (-get_frame_size ())))) = 1;
+
+ emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, OPTOP_REG)));
+}
+
+/* Generate rtl for the epilogue of the current function. */
+
+void
+pj_expand_epilogue ()
+{
+ if (frame_pointer_needed)
+ emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
+ else if (get_frame_size ())
+ emit_insn (gen_addsi3 (stack_pointer_rtx,
+ stack_pointer_rtx, GEN_INT (get_frame_size ())));
+ if (nfakes)
+ emit_insn (gen_addsi3 (gen_rtx_REG (SImode, OPTOP_REG),
+ gen_rtx_REG (SImode, OPTOP_REG),
+ GEN_INT (nfakes * 4)));
+
+
+ /* If this is a varargs function, then global0 is stashed away on
+ the top of the optop stack as the last secret argument by the
+ __vhelper. Pop off the va pointer provided too. */
+
+ if (current_function_varargs || current_function_stdarg)
+ emit_insn (gen_varargs_finish
+ (GEN_INT (current_function->args_info.named_words + 1)));
+
+ emit_insn (gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, OPTOP_REG)));
+}
+
+/* Return the opcode name for an instruction to load a standard
+ floating point constant, or NULL. */
+
+const char *
+pj_standard_float_constant (op)
+ rtx op;
+{
+ REAL_VALUE_TYPE r;
+ enum machine_mode mode = GET_MODE (op);
+
+ if (GET_CODE (op) != CONST_DOUBLE || (mode != DFmode && mode != SFmode))
+ return NULL;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (r, op);
+
+ if (REAL_VALUES_EQUAL (r, dconst0) && !REAL_VALUE_MINUS_ZERO (r))
+ return mode == DFmode ? "%*dconst_0" : "%*fconst_0";
+
+ if (REAL_VALUES_EQUAL (r, dconst1))
+ return mode == DFmode ? "%*dconst_1" : "%*fconst_1";
+
+ if (REAL_VALUES_EQUAL (r, dconst2))
+ return mode == DFmode ? 0 : "%*fconst_2";
+
+ return NULL;
+}
+
+/* Read the value at the current address, and decrement by the size.
+ The function is interesting because we're reading from high memory to low memory
+ and have to adjust the addresses of reads of 8 byte values
+ accordingly. */
+
+rtx
+pj_expand_builtin_va_arg (valist, type)
+ tree valist;
+ tree type;
+{
+ tree addr_tree, t;
+ HOST_WIDE_INT align;
+ HOST_WIDE_INT rounded_size;
+ rtx addr;
+
+ /* Compute the rounded size of the type. */
+ align = PARM_BOUNDARY / BITS_PER_UNIT;
+ rounded_size = (((int_size_in_bytes (type) + align - 1) / align) * align);
+
+ /* Get AP. */
+ addr_tree = valist;
+ addr = expand_expr (addr_tree, NULL_RTX, Pmode, EXPAND_NORMAL);
+ addr = copy_to_reg (addr);
+
+ /* Aggregates and large scalars are passed by reference. */
+ if (AGGREGATE_TYPE_P (type) || rounded_size > 8)
+ {
+ addr = gen_rtx_MEM (Pmode, addr);
+ rounded_size = 4;
+ }
+
+ /* adjust address to cope with double word sizes */
+ if (rounded_size > 4)
+ addr = gen_rtx_PLUS (Pmode, addr, GEN_INT (-4));
+
+ /* Compute new value for AP; AP = AP - SIZE */
+ t = build (MODIFY_EXPR, TREE_TYPE (valist), valist,
+ build (MINUS_EXPR, TREE_TYPE (valist), valist,
+ build_int_2 (rounded_size, 0)));
+
+ TREE_SIDE_EFFECTS (t) = 1;
+
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
+
+ return addr;
+}
+
+/* Return nonzero if the operand is valid as a source operand; it's
+ general and it's not an outgoing argument register. */
+
+int
+pj_source_operand (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ return !OUTGOING_REG_RTX_P (op) && general_operand (op, mode);
+}
+
+/* Return nonzero if the operator is a signed compare. */
+
+int
+pj_signed_comparison_operator (op, mode)
+ rtx op;
+ enum machine_mode mode;
+{
+ if (mode != GET_MODE (op))
+ return 0;
+
+ switch (GET_CODE (op))
+ {
+ case EQ:
+ case NE:
+ case LE:
+ case LT:
+ case GE:
+ case GT:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Return nonzero if the operator is an unsigned compare. */
+
+int
+pj_unsigned_comparison_operator (op, mode)
+ rtx op;
+ enum machine_mode mode ATTRIBUTE_UNUSED;
+{
+ if (mode != GET_MODE (op))
+ return 0;
+
+ switch (GET_CODE (op))
+ {
+ case GTU:
+ case GEU:
+ case LTU:
+ case LEU:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/* Helper function for pj_machine_dependent_reorg. Find the one
+ instance of register OP in the source part of PAT. If there are no
+ copies return NULL, if there are more than one, return NOT_UNIQUE. */
+
+#define NOT_UNIQUE (&const0_rtx)
+
+static rtx *
+unique_src_operand (pat, reg)
+ rtx *pat;
+ rtx reg;
+{
+ register rtx *result = 0;
+ register const char *fmt;
+ register int i;
+ register int j;
+
+ if (GET_CODE (*pat) == SET)
+ {
+ if (GET_CODE (XEXP (*pat, 0)) == MEM)
+ result = unique_src_operand (&XEXP (SET_DEST (*pat), 0), reg);
+ pat = &SET_SRC (*pat);
+ }
+
+ if (GET_CODE (*pat) == REG && REGNO (*pat) == REGNO (reg))
+ return pat;
+
+ fmt = GET_RTX_FORMAT (GET_CODE (*pat));
+ for (i = GET_RTX_LENGTH (GET_CODE (*pat)) - 1; i >= 0; i--)
+ {
+ if (fmt[i] == 'e')
+ {
+ rtx *new_result = unique_src_operand (&XEXP (*pat, i), reg);
+
+ if (new_result)
+ {
+ if (result)
+ return NOT_UNIQUE;
+ result = new_result;
+ }
+ }
+ else if (fmt[i] == 'E')
+ {
+ for (j = XVECLEN (*pat, i) - 1; j >= 0; j--)
+ {
+ rtx *new_result =
+ unique_src_operand (&XVECEXP (*pat, i, j), reg);
+
+ if (new_result)
+ {
+ if (result)
+ return NOT_UNIQUE;
+ result = new_result;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+/* Clean up the instructions to remove unneeded loads and stores.
+
+ For example, rewrite
+
+ iload a; iload b; iadd; istore z
+ iload z; iload c; iadd; istore z
+
+ as
+
+ iload a; iload b; iadd ; iload c; iadd; istore z
+
+ This function moves a cursor over each instruction, inspecting the
+ LOG_LINKS. Each of the cursor's LOG_LINK incoming instructions are
+ inspected, any which have a simple register destination which is
+ also used as a source in the cursor instruction, and aren't used
+ again between the the incoming instruction and the cursor, and
+ which become dead or set after the cursor get their sources
+ substituted into the position of the source register in the cursor
+ instruction. */
+
+void
+pj_machine_dependent_reorg (insns)
+ rtx insns;
+{
+ rtx cursor;
+
+ if (!optimize || !TARGET_REORG)
+ return;
+
+ for (cursor = insns; cursor; cursor = NEXT_INSN (cursor))
+ {
+ rtx links;
+ rtx cursor_pat;
+
+ /* We only care about INSNs, JUMP_INSNs. Ignore any special USE insns. */
+
+ if ((GET_CODE (cursor) != INSN && GET_CODE (cursor) != JUMP_INSN)
+ || GET_CODE (cursor_pat = PATTERN (cursor)) == USE
+ || GET_CODE (cursor_pat) == CLOBBER
+ || GET_CODE (cursor_pat) == ADDR_VEC
+ || GET_CODE (cursor_pat) == ADDR_DIFF_VEC)
+ continue;
+
+ for (links = LOG_LINKS (cursor); links; links = XEXP (links, 1))
+ {
+ rtx prev = XEXP (links, 0);
+ rtx prev_pat;
+ rtx prev_dest;
+ rtx prev_src;
+ rtx *dst_place;
+
+ if (GET_CODE (prev) == INSN
+ && GET_CODE (prev_pat = PATTERN (prev)) == SET
+ && GET_CODE (prev_dest = SET_DEST (prev_pat)) == REG
+ && dead_or_set_p (cursor, prev_dest)
+ && !reg_used_between_p (prev_dest, prev, cursor)
+ && no_labels_between_p (prev, cursor)
+ && no_jumps_between_p (prev, cursor)
+ && !modified_between_p ((prev_src = SET_SRC (prev_pat)), prev,
+ cursor)
+ && (dst_place = unique_src_operand (&cursor_pat, prev_dest))
+ && dst_place != NOT_UNIQUE
+ && REGNO (prev_dest) != OPTOP_REG
+ && GET_MODE (prev_dest) != XFmode
+ && GET_MODE (*dst_place) == GET_MODE (SET_DEST (prev_pat)))
+ {
+ *dst_place = SET_SRC (prev_pat);
+ PUT_CODE (prev, NOTE);
+ NOTE_LINE_NUMBER (prev) = NOTE_INSN_DELETED;
+ }
+ }
+ }
+}
diff --git a/gcc/config/pj/pj.h b/gcc/config/pj/pj.h
new file mode 100644
index 0000000..816fa89
--- /dev/null
+++ b/gcc/config/pj/pj.h
@@ -0,0 +1,1333 @@
+/* Definitions of target machine for GNU compiler for picoJava
+ Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Contributed by Steve Chamberlain of Transmeta (sac@pobox.com). */
+
+
+#define TARGET_VERSION fputs ("(picoJava)", stderr);
+
+/* We support two different default configurations. */
+#undef ASM_SPEC
+#ifdef TARGET_LITTLE_ENDIAN_DEFAULT
+#define CPP_SPEC "%{mb:-D__BIG_ENDIAN__ }%{!mb:-D__LITTLE_ENDIAN__ }"
+#define ASM_SPEC "%{mb:-mb }%{!mb:-ml }"
+#else
+#define CPP_SPEC "%{ml:-D__LITTLE_ENDIAN__ }%{!ml:-D__BIG_ENDIAN__}"
+#define ASM_SPEC "%{ml:-ml } %{!ml:-mb }"
+#endif
+
+#ifndef CPP_PREDEFINES
+#define CPP_PREDEFINES "-D__ELF__ -D__pj__ -Asystem(posix)"
+#endif
+
+/* Run-time compilation parameters selecting different hardware subsets. */
+
+extern int target_flags;
+
+#define LITTLE_ENDIAN_BIT (1<<0)
+#define EXTENSIONS_BIT (1<<1)
+#define PJ_TEST_BIT (1<<2)
+#define REORG_BIT (1<<3)
+
+/* Nonzero if generating code for a little endian pico java. */
+
+#define TARGET_LITTLE_ENDIAN (target_flags & LITTLE_ENDIAN_BIT)
+
+/* Nonzero to turn on internal tests. */
+
+#define TARGET_TEST (target_flags & PJ_TEST_BIT)
+
+/* Nonzero to turn on picoJava extensions. */
+
+#define TARGET_TM_EXTENSIONS (target_flags & EXTENSIONS_BIT)
+
+/* Nonzero to turn on the reorganization pass. */
+
+#define TARGET_REORG (target_flags & REORG_BIT)
+
+#ifdef TARGET_LITTLE_ENDIAN_DEFAULT
+#define TARGET_DEFAULT (LITTLE_ENDIAN_BIT|EXTENSIONS_BIT|REORG_BIT)
+#else
+#define TARGET_DEFAULT REORG_BIT
+#endif
+
+#define TARGET_SWITCHES \
+{ {"l", LITTLE_ENDIAN_BIT, "Generate little endian data" }, \
+ {"b", -LITTLE_ENDIAN_BIT, "Generate big endian data" }, \
+ {"t", PJ_TEST_BIT, "Turn on maintainer testing code" }, \
+ {"ext", EXTENSIONS_BIT, "Enable Transmeta picoJava extensions" }, \
+ {"no-ext", -EXTENSIONS_BIT, "Disable Transmeta picoJava extensions" }, \
+ {"no-reorg", -REORG_BIT, "Disable reorganization pass" }, \
+ {"", TARGET_DEFAULT, 0 }}
+
+/* Sometimes certain combinations of command options do not make
+ sense on a particular target machine. You can define a macro
+ `OVERRIDE_OPTIONS' to take account of this. This macro, if
+ defined, is executed once just after all the command options have
+ been parsed.
+
+ Don't use this macro to turn on various extra optimizations for
+ `-O'. That is what `OPTIMIZATION_OPTIONS' is for.
+
+ We take this chance to register the global variables with the garbage
+ collector. */
+
+#define OVERRIDE_OPTIONS \
+ do { \
+ ggc_add_rtx_root (&pj_cmp_op0, 1); \
+ ggc_add_rtx_root (&pj_cmp_op1, 1); \
+ } while (0)
+
+/* Define this to change the optimizations performed by default. */
+#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) \
+ do { \
+ if (optimize) \
+ flag_force_addr = 1; \
+ } while (0)
+
+/* Target machine storage layout. */
+
+/* Define to use software floating point emulator for REAL_ARITHMETIC and
+ decimal <-> binary conversion. */
+#define REAL_ARITHMETIC
+
+/* Define this if most significant bit is lowest numbered
+ in instructions that operate on numbered bit-fields. */
+#define BITS_BIG_ENDIAN 0
+
+/* Define this if most significant byte of a word is the lowest numbered. */
+#define BYTES_BIG_ENDIAN (TARGET_LITTLE_ENDIAN == 0)
+
+/* Define this if most significant word of a multiword number is the lowest
+ numbered. */
+#define WORDS_BIG_ENDIAN (TARGET_LITTLE_ENDIAN == 0)
+
+/* Define this to set the endianness to use in libgcc2.c, which can
+ not depend on target_flags. */
+#if defined(TARGET_LITTLE_ENDIAN_DEFAULT)
+#define LIBGCC2_WORDS_BIG_ENDIAN 0
+#else
+#define LIBGCC2_WORDS_BIG_ENDIAN 1
+#endif
+
+/* Number of bits in an addressable storage unit. */
+#define BITS_PER_UNIT 8
+
+/* Width in bits of a "word", which is the contents of a machine register.
+ Note that this is not necessarily the width of data type `int';
+ if using 16-bit ints on a 68000, this would still be 32.
+ But on a machine with 16-bit registers, this would be 16. */
+#define BITS_PER_WORD 32
+#define MAX_BITS_PER_WORD 32
+
+/* Width of a word, in units (bytes). */
+#define UNITS_PER_WORD 4
+
+/* Width in bits of a pointer.
+ See also the macro `Pmode' defined below. */
+#define POINTER_SIZE 32
+
+/* Allocation boundary (in *bits*) for storing arguments in argument list. */
+#define PARM_BOUNDARY 32
+
+/* Boundary (in *bits*) on which stack pointer should be aligned. */
+#define STACK_BOUNDARY 32
+
+/* Allocation boundary (in *bits*) for the code of a function. */
+#define FUNCTION_BOUNDARY 8
+
+/* Alignment of field after `int : 0' in a structure. */
+#define EMPTY_FIELD_BOUNDARY 32
+
+/* No data type wants to be aligned rounder than this. */
+#define BIGGEST_ALIGNMENT 32
+
+/* The best alignment to use in cases where we have a choice. */
+#define FASTEST_ALIGNMENT 32
+
+/* Make strings word-aligned so strcpy from constants will be faster. */
+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
+ ((TREE_CODE (EXP) == STRING_CST \
+ && (ALIGN) < FASTEST_ALIGNMENT) \
+ ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Make arrays of chars word-aligned for the same reasons. */
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+ (TREE_CODE (TYPE) == ARRAY_TYPE \
+ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
+ && (ALIGN) < FASTEST_ALIGNMENT ? FASTEST_ALIGNMENT : (ALIGN))
+
+/* Set this non-zero if move instructions will actually fail to work
+ when given unaligned data. */
+#define STRICT_ALIGNMENT 1
+
+
+/* Standard register usage. */
+
+/* Enumerate the hardware registers. */
+
+enum
+{
+ R0_REG, R1_REG, R2_REG, R3_REG,
+ R4_REG, R5_REG, R6_REG, R7_REG,
+ R8_REG, R9_REG, R10_REG, R11_REG,
+ R12_REG, R13_REG, R14_REG, R15_REG,
+
+ R16_REG, R17_REG, R18_REG, R19_REG,
+ R20_REG, R21_REG, R22_REG, R23_REG,
+ R24_REG, R25_REG, R26_REG, R27_REG,
+ R28_REG, R29_REG, R30_REG, R31_REG,
+
+ I0_REG, I1_REG, I2_REG, I3_REG,
+ I4_REG, I5_REG, I6_REG, I7_REG,
+ I8_REG, I9_REG, I10_REG, I11_REG,
+ I12_REG, I13_REG, I14_REG, I15_REG,
+
+ I16_REG, I17_REG, I18_REG, I19_REG,
+ I20_REG, I21_REG, I22_REG, I23_REG,
+ I24_REG, I25_REG, I26_REG, I27_REG,
+ I28_REG, I29_REG, I30_REG, ISC_REG,
+
+ G0_REG, G1_REG, G2_REG, G3_REG,
+ G4_REG, G5_REG, G6_REG, G7_REG,
+ VARS_REG, OPTOP_REG, SC_REG, PC_REG,
+ TICKS_REG, SLOW_REG, VA_REG, D3_REG,
+
+ D4_REG, D5_REG, D6_REG, D7_REG,
+ Q0_REG, Q1_REG, Q2_REG, Q3_REG,
+ P0_REG, P1_REG, P2_REG, P3_REG,
+ P4_REG, P5_REG, P6_REG, P7_REG,
+
+ O0_REG, O1_REG, O2_REG, O3_REG,
+ O4_REG, O5_REG, O6_REG, O7_REG,
+ O8_REG, O9_REG, O10_REG, O11_REG,
+ O12_REG, O13_REG, O14_REG, O15_REG,
+
+ O16_REG, O17_REG, O18_REG, O19_REG,
+ O20_REG, O21_REG, O22_REG, O23_REG,
+ O24_REG, O25_REG, O26_REG, O27_REG,
+ O28_REG, O29_REG, O30_REG, OSC_REG,
+
+ LAST_O_REG=OSC_REG,
+ LAST_R_REG=R31_REG,
+ LAST_I_REG=ISC_REG,
+ LAST_S_REG=P7_REG,
+
+};
+
+/* Useful predicates. */
+
+#define STACK_REGNO_P(REGNO) \
+ (((unsigned) (REGNO)) <= LAST_I_REG)
+
+#define OUTGOING_REGNO_P(REGNO) \
+ (((REGNO) >= O0_REG) && ((REGNO) <= LAST_O_REG))
+
+#define INCOMING_REGNO_P(REGNO) \
+ (((REGNO) >= I0_REG) && ((REGNO) <= LAST_I_REG))
+
+#define STACK_REG_RTX_P(RTX) \
+ (GET_CODE (RTX) == REG && STACK_REGNO_P (REGNO (RTX)))
+
+#define OUTGOING_REG_RTX_P(RTX) \
+ (GET_CODE (RTX) == REG && OUTGOING_REGNO_P (REGNO (RTX)))
+
+#define OPTOP_REG_RTX_P(RTX) \
+ (GET_CODE (RTX) == REG && REGNO (RTX) == OPTOP_REG)
+
+#define FIRST_PSEUDO_REGISTER 128
+
+/* 1 for registers that have pervasive standard uses
+ and are not available for the register allocator. */
+
+#define FIXED_REGISTERS \
+ { \
+ 0,0,0,0, 0,0,0,0, /* r0 .. r7 */ \
+ 0,0,0,0, 0,0,0,0, /* r8 .. r15 */ \
+ 0,0,0,0, 0,0,0,0, /* r16.. r23 */ \
+ 0,0,0,0, 0,0,0,0, /* r24.. r31 */ \
+ \
+ 0,0,0,0, 0,0,0,0, /* i0 .. i7 */ \
+ 0,0,0,0, 0,0,0,0, /* i8 .. i15 */ \
+ 0,0,0,0, 0,0,0,0, /* i16.. i23 */ \
+ 0,0,0,0, 0,0,0,0, /* i24.. i31 */ \
+ \
+ 1,0,0,1, 1,1,1,1, /* g0 .. g7 */ \
+ 1,1,1,1, 1,1,1,1, /* vars, optop, sc, pc, ticks, slow, va, sgo */ \
+ 1,1,1,1, 1,1,1,1, /* d4 d5 d6 ap p0 p1 p2 p3 */ \
+ 1,1,1,1, 1,1,1,1, /* q1 .. q7 */ \
+ \
+ 0,0,0,0, 0,0,0,0, /* o0 .. o7 */ \
+ 0,0,0,0, 0,0,0,0, /* o8 .. o15 */ \
+ 0,0,0,0, 0,0,0,0, /* o16.. o23 */ \
+ 0,0,0,0, 0,0,0,0 } /* o24.. o31 */
+
+
+/* 1 for registers not available across function calls.
+ These must include the FIXED_REGISTERS and also any
+ registers that can be used without being saved.
+ The latter must include the registers where values are returned
+ and the register where structure-value addresses are passed.
+ Aside from that, you can include as many other registers as you like.
+
+ We pretend that some standard registers are call clobbered so the
+ exception handler code has somewhere to play. */
+
+#define CALL_USED_REGISTERS \
+ { \
+ 0,0,0,0, 0,0,0,0, /* r0 ..r7 */ \
+ 0,0,0,0, 0,0,0,0, /* r8 ..r15 */ \
+ 0,0,0,0, 1,1,1,1, /* r16..r23 */ \
+ 1,1,1,1, 1,1,1,1, /* r24..r31 */ \
+ \
+ 0,0,0,0, 0,0,0,0, /* i0 ..i7 */ \
+ 0,0,0,0, 0,0,0,0, /* i8 ..i15 */ \
+ 0,0,0,0, 0,0,0,0, /* i16..i23 */ \
+ 0,0,0,0, 0,0,0,0, /* i24..i31 */ \
+ \
+ 1,1,1,1, 0,0,0,0, /* g0 ..g7 */ \
+ 1,1,1,1, 1,1,1,1, /* vars, optop, sc, pc, ticls, slow, va, sgo */ \
+ 1,1,1,1, 1,1,1,1, /* d4 d5 d6 ap p0..p3*/ \
+ 1,1,1,1, 1,1,1,1, /* q0..q7 */ \
+ \
+ 1,1,1,1, 1,1,1,1, /* o0 ..o7 */ \
+ 1,1,1,1, 1,1,1,1, /* o8 ..o15 */ \
+ 1,1,1,1, 1,1,1,1, /* o16..o23 */ \
+ 1,1,1,1, 1,1,1,1 } /* o24..o31 */
+
+/* Return number of consecutive hard regs needed starting at reg REGNO
+ to hold something of mode MODE.
+ This is ordinarily the length in words of a value of mode MODE
+ but can be less for certain modes in special long registers. */
+
+#define HARD_REGNO_NREGS(REGNO, MODE) \
+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
+
+ We can allow any mode in the general register or the result
+ register. It's only safe to put up to 4 bytes values elsewhere. */
+
+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
+ (((REGNO) <= LAST_R_REG || (REGNO) == G1_REG || GET_MODE_SIZE(MODE) <= 4 ) && !OUTGOING_REGNO_P(REGNO))
+
+/* Value is 1 if it is a good idea to tie two pseudo registers
+ when one has mode MODE1 and one has mode MODE2.
+ If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
+ for any hard reg, then this must be 0 for correct output. */
+#define MODES_TIEABLE_P(MODE1, MODE2) 1
+
+/* Specify the registers used for certain standard purposes.
+ The values of these macros are register numbers. */
+
+/* Define this if the program counter is overloaded on a register. */
+#define PC_REGNUM PC_REG
+
+/* Register to use for pushing function arguments. */
+#define STACK_POINTER_REGNUM G0_REG
+
+/* Base register for access to local variables of the function. */
+#define FRAME_POINTER_REGNUM R31_REG
+
+/* Base register for access to arguments of the function. */
+#define ARG_POINTER_REGNUM R30_REG
+
+/* Register in which the static-chain is passed to a function. */
+#define STATIC_CHAIN_REGNUM G1_REG
+
+/* Value should be nonzero if functions must have frame pointers.
+ Zero means the frame pointer need not be set up (and parms may be
+ accessed via the stack pointer) in functions that seem suitable. */
+#define FRAME_POINTER_REQUIRED 0
+
+/* This is an array of structures. Each structure initializes one pair
+ of eliminable registers. The "from" register number is given first,
+ followed by "to". Eliminations of the same "from" register are listed
+ in order of preference. */
+
+#define ELIMINABLE_REGS \
+ { { VA_REG, STACK_POINTER_REGNUM }, \
+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM } }
+
+/* Given FROM and TO register numbers, say whether this elimination
+ is allowed. */
+#define CAN_ELIMINATE(FROM, TO) 1
+
+/* Define the offset between two registers, one to be eliminated, and the other
+ its replacement, at the start of a routine. */
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
+ OFFSET = (((FROM) == FRAME_POINTER_REGNUM) ? get_frame_size() : 0)
+
+/* For picoJava we have to save 12 bytes of information for a non local
+ jump. */
+
+#define STACK_SAVEAREA_MODE(x) ((x)==SAVE_NONLOCAL ? XFmode : Pmode)
+
+/* If the structure value address is not passed in a register, define
+ `STRUCT_VALUE' as an expression returning an RTX for the place
+ where the address is passed. If it returns 0, the address is
+ passed as an "invisible" first argument. */
+#define STRUCT_VALUE 0
+
+/* A C expression which can inhibit the returning of certain function
+ values in registers, based on the type of value. A nonzero value
+ says to return the function value in memory, just as large
+ structures are always returned. Here TYPE will be a C expression
+ of type `tree', representing the data type of the value.
+
+ Note that values of mode `BLKmode' must be explicitly handled by
+ this macro. Also, the option `-fpcc-struct-return' takes effect
+ regardless of this macro. On most systems, it is possible to
+ leave the macro undefined; this causes a default definition to be
+ used, whose value is the constant 1 for `BLKmode' values, and 0
+ otherwise.
+
+ Do not use this macro to indicate that structures and unions
+ should always be returned in memory. You should instead use
+ `DEFAULT_PCC_STRUCT_RETURN' to indicate this. */
+#define RETURN_IN_MEMORY(TYPE) \
+ ((TYPE_MODE (TYPE) == BLKmode) || int_size_in_bytes (TYPE) > 8)
+
+/* Don't default to pcc-struct-return, because we have already specified
+ exactly how to return structures in the RETURN_IN_MEMORY macro. */
+#define DEFAULT_PCC_STRUCT_RETURN 0
+
+/* Define the classes of registers for register constraints in the
+ machine description. Also define ranges of constants.
+
+ One of the classes must always be named ALL_REGS and include all hard regs.
+ If there is more than one class, another class must be named NO_REGS
+ and contain no registers.
+
+ The name GENERAL_REGS must be the name of a class (or an alias for
+ another name such as ALL_REGS). This is the class of registers
+ that is allowed by "g" or "r" in a register constraint.
+ Also, registers outside this class are allocated only when
+ instructions express preferences for them.
+
+ The classes must be numbered in nondecreasing order; that is,
+ a larger-numbered class must never be contained completely
+ in a smaller-numbered class.
+
+ For any two classes, it is very desirable that there be another
+ class that represents their union. */
+
+enum reg_class
+{
+ NO_REGS,
+ OUT_REGS, /* Registers for passing outgoing parameters. */
+ STD_REGS, /* Standard registers, on opstack. */
+ ARG_REGS, /* Incoming argument registers. */
+ SRC_REGS, /* All registers valid as a source. */
+ DST_REGS, /* All registers valid as a destination. */
+ ALL_REGS,
+ LIM_REG_CLASSES,
+};
+
+#define GENERAL_REGS SRC_REGS
+#define N_REG_CLASSES (int) LIM_REG_CLASSES
+
+/* Give names of register classes as strings for dump files. */
+#define REG_CLASS_NAMES \
+{ \
+ "NO_REGS", \
+ "OUT_REGS", \
+ "STD_REGS", \
+ "ARG_REGS", \
+ "SRC_REGS", \
+ "DST_REGS", \
+ "ALL_REGS", \
+}
+
+/* Define which registers fit in which classes.
+ This is an initializer for a vector of HARD_REG_SET
+ of length N_REG_CLASSES. */
+
+#define REG_CLASS_CONTENTS \
+{ \
+ { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* NO_REGS */ \
+ { 0x00000000, 0x00000000, 0x00000000, 0xffffffff }, /* OUT_REGS */ \
+ { 0xffffffff, 0x00000000, 0x00000000, 0x00000000 }, /* STD_REGS */ \
+ { 0x00000000, 0xffffffff, 0x00000000, 0x00000000 }, /* ARG_REGS */ \
+ { 0xffffffff, 0xffffffff, 0x000fff0f, 0x00000000 }, /* SRC_REGS */ \
+ { 0xffffffff, 0xffffffff, 0x000fff0f, 0xffffffff }, /* DST_REGS */ \
+ { 0xffffffff, 0xffffffff, 0x000fff0f, 0xffffffff }, /* ALL_REGS */ \
+}
+
+/* The same information, inverted:
+ Return the class number of the smallest class containing
+ reg number REGNO. This could be a conditional expression
+ or could index an array. */
+
+#define REGNO_REG_CLASS(REGNO) \
+ ( ((REGNO) <= LAST_R_REG) ? STD_REGS \
+ : ((REGNO) <= LAST_I_REG) ? ARG_REGS \
+ : ((REGNO) <= LAST_S_REG) ? SRC_REGS \
+ : OUT_REGS)
+
+/* The class value for index registers, and the one for base regs. */
+#define INDEX_REG_CLASS GENERAL_REGS
+#define BASE_REG_CLASS GENERAL_REGS
+
+/* Get reg_class from a letter such as appears in the machine
+ description. */
+
+#define REG_CLASS_FROM_LETTER(C) \
+ ( (C) == 'S' ? SRC_REGS \
+ : (C) == 'D' ? DST_REGS \
+ : NO_REGS)
+
+/* The letters I, J, K, L and M in a register constraint string
+ can be used to stand for particular ranges of immediate operands.
+ This macro defines what the ranges are.
+ C is the letter, and VALUE is a constant value.
+ Return 1 if VALUE is in the range specified by C.
+
+ I: arithmetic operand -127..128, as used in inc.
+ K: 0.
+ */
+
+#define CONST_OK_FOR_I(VALUE) \
+ (((HOST_WIDE_INT)(VALUE))>= -128 && ((HOST_WIDE_INT)(VALUE)) <= 127)
+
+#define CONST_OK_FOR_K(VALUE) ((VALUE)==0)
+
+#define CONST_OK_FOR_LETTER_P(VALUE, C) \
+ ((C) == 'I' ? CONST_OK_FOR_I (VALUE) \
+ : (C) == 'K' ? CONST_OK_FOR_K (VALUE) \
+ : 0)
+
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
+
+/* Given an rtx X being reloaded into a reg required to be
+ in class CLASS, return the class of reg to actually use.
+ In general this is just CLASS; but on some machines
+ in some cases it is preferable to use a more restrictive class. */
+
+#define PREFERRED_RELOAD_CLASS(X, CLASS) (CLASS)
+
+/* Return the maximum number of consecutive registers
+ needed to represent mode MODE in a register of class CLASS.
+
+ With picoJava this is the size of MODE in words. */
+
+#define CLASS_MAX_NREGS(CLASS, MODE) \
+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
+
+
+/* A C expression whose value is nonzero if pseudos that have been
+ assigned to registers of class CLASS would likely be spilled
+ because registers of CLASS are needed for spill registers.
+
+ For picoJava, something that isn't an incoming argument or a normal
+ register is going to be very hard to get at. */
+
+#define CLASS_LIKELY_SPILLED_P(X) ((X) != STD_REGS && (X) != ARG_REGS)
+
+/* Stack layout; function entry, exit and calling. */
+
+/* Define this if pushing a word on the stack
+ makes the stack pointer a smaller address. */
+
+#define STACK_GROWS_DOWNWARD 1
+
+/* Define this macro if successive arguments to a function occupy
+ decreasing addresses on the stack. */
+
+#define ARGS_GROW_DOWNWARD 1
+
+/* Define this macro if the addresses of local variable slots are at
+ negative offsets from the frame pointer. */
+
+#define FRAME_GROWS_DOWNWARD 1
+
+/* Offset from the frame pointer to the first local variable slot to
+ be allocated. */
+
+#define STARTING_FRAME_OFFSET 0
+
+/* If we generate an insn to push BYTES bytes,
+ this says how many the stack pointer really advances by. */
+
+/* Don't define PUSH_ROUNDING, since the hardware doesn't do this.
+ When PUSH_ROUNDING is not defined, PARM_BOUNDARY will cause gcc to
+ do correct alignment. */
+
+#define PUSH_ROUNDING(NPUSHED) (((NPUSHED) + 3) & ~3)
+
+/* Offset of first parameter from the argument pointer register value. */
+
+#define FIRST_PARM_OFFSET(FNDECL) 0
+
+/* Value is the number of byte of arguments automatically
+ popped when returning from a subroutine call.
+ FUNDECL is the declaration node of the function (as a tree),
+ FUNTYPE is the data type of the function (as a tree),
+ or for a library call it is an identifier node for the subroutine name.
+ SIZE is the number of bytes of arguments passed on the stack. */
+
+#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
+
+/* Define how to find the value returned by a function.
+ VALTYPE is the data type of the value (as a tree).
+ If the precise function being called is known, FUNC is its FUNCTION_DECL;
+ otherwise, FUNC is 0. */
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+ gen_rtx_REG (TYPE_MODE (VALTYPE), G1_REG)
+
+/* 1 if N is a possible register number for a function value
+ as seen by the caller. */
+
+#define FUNCTION_VALUE_REGNO_P(N) \
+ ((N) == G1_REG)
+
+/* 1 if N is a possible register number for function argument passing. */
+#define FUNCTION_ARG_REGNO_P(N) 0
+
+/* Define how to find the value returned by a library function
+ assuming the value has mode MODE. */
+
+#define LIBCALL_VALUE(MODE) \
+ gen_rtx_REG (MODE, G1_REG)
+
+/* Define this macro to be a nonzero value if the location where a
+ function argument is passed depends on whether or not it is a
+ named argument. */
+
+#define STRICT_ARGUMENT_NAMING 1
+
+/* Define a data type for recording info about an argument list
+ during the scan of that argument list. This data type should
+ hold all necessary information about the function itself
+ and about the args processed so far, enough to enable macros
+ such as FUNCTION_ARG to determine where the next arg should go.
+
+ For picoJava this is a struct which remembers the number of
+ arguments named, the total number of words passed and an adjustment
+ factor to use if accessing a double word argument with a single
+ word memop. See the comments at the head pj.c for more information */
+
+#define ARGS_IN_REGS 32
+
+struct pj_args
+{
+ int named_words;
+ int total_words;
+ int arg_count;
+ int arg_adjust[ARGS_IN_REGS];
+};
+
+#define CUMULATIVE_ARGS struct pj_args
+
+#define FUNCTION_INCOMING_ARG(asf,pmode,passtyped,named) \
+ pj_function_incoming_arg(&asf,pmode,passtyped,named)
+
+/* Initialize a variable CUM of type CUMULATIVE_ARGS
+ for a call to a function whose data type is FNTYPE.
+ For a library call, FNTYPE is 0.
+ */
+
+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT) \
+ (CUM).named_words = 0; \
+ (CUM).total_words = 0; \
+ (CUM).arg_count = 0;
+
+/* Update the data in CUM to advance over an argument
+ of mode MODE and data type TYPE.
+
+ picoJava only ever sends scalars as arguments. Aggregates are sent
+ by reference. */
+
+#define PJ_ARG_WORDS(MODE) \
+ ((GET_MODE_SIZE (MODE) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
+
+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
+{ \
+ (CUM).total_words += PJ_ARG_WORDS (MODE); \
+ if (NAMED) \
+ (CUM).named_words += PJ_ARG_WORDS (MODE); \
+ (CUM).arg_count++; \
+}
+
+/* Define where to put the arguments to a function.
+ Value is zero to push the argument on the stack,
+ or a hard register in which to store the argument.
+
+ MODE is the argument's machine mode.
+ TYPE is the data type of the argument (as a tree).
+ This is null for libcalls where that information may
+ not be available.
+ CUM is a variable of type CUMULATIVE_ARGS which gives info about
+ the preceding args and about the function being called.
+ NAMED is nonzero if this argument is a named parameter
+ (otherwise it is an extra parameter matching an ellipsis).
+
+ For picoJava scalar arguments are normally in registers. */
+
+
+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
+ ( ((CUM).total_words + PJ_ARG_WORDS (MODE) < ARGS_IN_REGS) \
+ ? gen_rtx (REG, MODE, O0_REG + (CUM).total_words) \
+ : NULL_RTX)
+
+
+/* A C expression that indicates when an argument must be passed by
+ reference. If nonzero for an argument, a copy of that argument is
+ made in memory and a pointer to the argument is passed instead of
+ the argument itself. The pointer is passed in whatever way is
+ appropriate for passing a pointer to that type. */
+
+/* All aggregates and arguments larger than 8 bytes are passed this way. */
+
+#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
+ (TYPE && (AGGREGATE_TYPE_P (TYPE) || int_size_in_bytes (TYPE) > 8))
+
+/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
+ the stack pointer does not matter. The value is tested only in
+ functions that have frame pointers.
+ No definition is equivalent to always zero. */
+
+#define EXIT_IGNORE_STACK 0
+
+/* Trampoline support. */
+
+/* A picoJava trampoline looks like:
+
+ 0000 11DEAD sipush %lo16(static)
+ 0003 EDDEAD sethi %hi16(static)
+ 0006 FF7D write_global1
+ 0008 11DEAD sipush %lo16(fn)
+ 000b EDDEAD sethi %hi16(fn)
+ 000e FF60 write_pc
+*/
+
+/* Length in units of the trampoline for entering a nested function. */
+#define TRAMPOLINE_SIZE 16
+
+/* Alignment required for a trampoline in bits . */
+#define TRAMPOLINE_ALIGNMENT 32
+
+#define TRAMPOLINE_TEMPLATE(FILE) \
+ fprintf (FILE, "\tsipush 0xdead\n"); \
+ fprintf (FILE, "\tsethi 0xdead\n"); \
+ fprintf (FILE, "\twrite_global1\n"); \
+ fprintf (FILE, "\tsipush 0xdead\n"); \
+ fprintf (FILE, "\tsethi 0xdead\n"); \
+ fprintf (FILE, "\twrite_pc\n");
+
+/* Emit RTL insns to initialize the variable parts of a trampoline.
+ FNADDR is an RTX for the address of the function's pure code.
+ CXT is an RTX for the static chain value for the function. */
+
+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
+{ \
+ static int off[4] = { 1, 0, 4, 3 }; \
+ int i; \
+ \
+ /* Move the FNADDR and CXT into the instruction stream. Do this byte \
+ by byte to make sure it works for either endianness. */ \
+ \
+ for (i = 0; i < 4; i++) \
+ emit_move_insn \
+ (gen_rtx_MEM (QImode, \
+ plus_constant (tramp, off[i] + 1)), \
+ gen_rtx_TRUNCATE (QImode, \
+ expand_shift (RSHIFT_EXPR, SImode, \
+ CXT, size_int (i * 8), 0, 1))); \
+ \
+ for (i = 0; i < 4; i++) \
+ emit_move_insn \
+ (gen_rtx_MEM (QImode, \
+ plus_constant (tramp, off[i] + 9)), \
+ gen_rtx_TRUNCATE (QImode, \
+ expand_shift (RSHIFT_EXPR, SImode, \
+ FNADDR, size_int (i * 8), 0, 1))); \
+}
+
+/* Output assembler code to FILE to increment profiler label # LABELNO
+ for profiling a function entry. */
+
+#define FUNCTION_PROFILER(FILE, LABELNO) \
+ fprintf (FILE, "\tsipush %%lo16(.LP%d)\n", (LABELNO)); \
+ fprintf (FILE, "\tsethi %%hi16(.LP%d)\n", (LABELNO)); \
+ fprintf (FILE, "\tsipush %%lo16(_mcount)\n"); \
+ fprintf (FILE, "\tsethi %%hi16(_mcount)\n"); \
+ fprintf (FILE, "\ticonst_3\n"); \
+ fprintf (FILE, "\tcall\n");
+
+
+/* Addressing modes, and classification of registers for them. */
+
+#define HAVE_POST_INCREMENT 1
+#define HAVE_PRE_INCREMENT 1
+#define HAVE_POST_DECREMENT 1
+#define HAVE_PRE_DECREMENT 1
+
+/* These assume that REGNO is a hard or pseudo reg number.
+ They give nonzero only if REGNO is a hard reg of the suitable class
+ or a pseudo reg currently allocated to a suitable hard reg.
+ Since they use reg_renumber, they are safe only once reg_renumber
+ has been allocated, which happens in local-alloc.c. */
+
+/* Any register is OK for a base or an index. As is something that has
+ been spilled to memory. */
+
+#define REGNO_OK_FOR_BASE_P(REGNO) 1
+#define REGNO_OK_FOR_INDEX_P(REGNO) 1
+
+/* Maximum number of registers that can appear in a valid memory
+ address.
+
+ Arbitarily limited to 20. */
+
+#define MAX_REGS_PER_ADDRESS 20
+
+/* Recognize any constant value that is a valid address. */
+
+#define CONSTANT_ADDRESS_P(X) \
+ (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
+ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST)
+
+/* Nonzero if the constant value X is a legitimate general operand. */
+
+#define LEGITIMATE_CONSTANT_P(X) \
+ (GET_CODE (X) == CONST_DOUBLE ? (pj_standard_float_constant (X)!=0) : 1)
+
+/* Letters in the range `Q' through `U' in a register constraint string
+ may be defined in a machine-dependent fashion to stand for arbitrary
+ operand types.
+
+ For picoJava, `S' handles a source operand. */
+
+#define EXTRA_CONSTRAINT(OP, C) \
+ ((C) == 'S' ? pj_source_operand (OP, GET_MODE (OP)) : 0)
+
+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx and
+ check its validity for a certain class. */
+
+#define REG_OK_FOR_BASE_P(X) 1
+#define REG_OK_FOR_INDEX_P(x) 0
+
+
+/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
+ that is a valid memory address for an instruction.
+ The MODE argument is the machine mode for the MEM expression
+ that wants to use this address.
+
+ We may have arbitrarily complex addressing modes, but we get better
+ cse of address expressions if we generate code with simple
+ addressing modes and clean up redundant register operations later
+ in the machine dependent reorg pass. */
+
+#define SRC_REG_P(X) \
+ (REG_P(X) && !OUTGOING_REG_RTX_P (X))
+
+#define SIMPLE_ADDRESS(X) \
+ (SRC_REG_P(X) || CONSTANT_ADDRESS_P(X))
+
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
+ if (SIMPLE_ADDRESS(X)) goto LABEL; \
+ if ((GET_CODE (X) == POST_INC \
+ || GET_CODE (X) == PRE_INC \
+ || GET_CODE (X) == POST_DEC \
+ || GET_CODE (X) == PRE_DEC) && SRC_REG_P(XEXP (X, 0))) goto LABEL; \
+
+/* Try machine-dependent ways of modifying an illegitimate address
+ to be legitimate. If we find one, return the new, valid address.
+ This macro is used in only one place: `memory_address' in explow.c.
+
+ OLDX is the address as it was before break_out_memory_refs was called.
+ In some cases it is useful to look at this to decide what needs to be done.
+
+ MODE and WIN are passed so that this macro can use
+ GO_IF_LEGITIMATE_ADDRESS.
+
+ It is always safe for this macro to do nothing. It exists to recognize
+ opportunities to optimize the output. */
+
+#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)
+
+/* Go to LABEL if ADDR (a legitimate address expression)
+ has an effect that depends on the machine mode it is used for. */
+
+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
+{ \
+ if (GET_CODE(ADDR) == PRE_DEC || GET_CODE(ADDR) == POST_INC \
+ || GET_CODE(ADDR) == PRE_INC || GET_CODE(ADDR) == POST_DEC) \
+ goto LABEL; \
+}
+
+/* Specify the machine mode that this machine uses
+ for the index in the tablejump instruction. */
+#define CASE_VECTOR_MODE SImode
+
+/* Define as C expression which evaluates to nonzero if the tablejump
+ instruction expects the table to contain offsets from the address of the
+ table. */
+
+#define CASE_VECTOR_PC_RELATIVE 1
+
+/* Specify the tree operation to be used to convert reals to integers. */
+#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
+
+/* This is the kind of divide that is easiest to do in the general case. */
+#define EASY_DIV_EXPR TRUNC_DIV_EXPR
+
+/* 'char' is signed by default. */
+#define DEFAULT_SIGNED_CHAR 1
+
+/* The type of size_t unsigned int. */
+#define SIZE_TYPE "unsigned int"
+
+/* Don't cse the address of the function being compiled. */
+
+#define NO_RECURSIVE_FUNCTION_CSE (!optimize_size)
+
+/* Max number of bytes we can move from memory to memory
+ in one reasonably fast instruction. */
+
+#define MOVE_MAX 4
+
+/* Max number of bytes we want move_by_pieces to be able to copy
+ efficiently. */
+
+#define MOVE_MAX_PIECES 4
+
+/* Define if operations between registers always perform the operation
+ on the full register even if a narrower mode is specified. */
+/*#define WORD_REGISTER_OPERATIONS*/
+
+/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
+ will either zero-extend or sign-extend. The value of this macro should
+ be the code that says which one of the two operations is implicitly
+ done, NIL if none. */
+
+#define LOAD_EXTEND_OP(MODE) SIGN_EXTEND
+
+/* Define if loading short immediate values into registers sign extends. */
+
+#define SHORT_IMMEDIATES_SIGN_EXTEND
+
+/* Define this if zero-extension is slow (more than one real
+ instruction). */
+
+/* #define SLOW_ZERO_EXTEND */
+
+/* Nonzero if access to memory by bytes is no faster than for words. */
+#define SLOW_BYTE_ACCESS 1
+
+#define INT_TYPE_SIZE 32
+
+/* A C expression that is nonzero if on this machine the number of
+ bits actually used for the count of a shift operation is equal to the
+ number of bits needed to represent the size of the object being
+ shifted. */
+
+#define SHIFT_COUNT_TRUNCATED 1
+
+/* All integers have the same format so truncation is easy. */
+
+#define TRULY_NOOP_TRUNCATION(OUTPREC,INPREC) 1
+
+/* Define this if addresses of constant functions
+ shouldn't be put through pseudo regs where they can be cse'd.
+ Desirable on machines where ordinary constants are expensive
+ but a CALL with constant address is cheap. */
+
+#define NO_FUNCTION_CSE (!optimize_size)
+
+/* Chars and shorts should be passed as ints. */
+
+#define PROMOTE_PROTOTYPES 1
+
+/* The machine modes of pointers and functions. */
+
+#define Pmode SImode
+#define FUNCTION_MODE Pmode
+
+
+/* A part of a C `switch' statement that describes the relative costs
+ of constant RTL expressions. It must contain `case' labels for
+ expression codes `const_int', `const', `symbol_ref', `label_ref'
+ and `const_double'. Each case must ultimately reach a `return'
+ statement to return the relative cost of the use of that kind of
+ constant value in an expression. The cost may depend on the
+ precise value of the constant, which is available for examination
+ in X, and the rtx code of the expression in which it is contained,
+ found in OUTER_CODE.
+
+ CODE is the expression code--redundant, since it can be obtained
+ with `GET_CODE (X)'. */
+
+#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
+ case CONST_INT: \
+ return INTVAL (RTX) >= -1 && INTVAL (RTX) <= 5 ? 1 \
+ : INTVAL (RTX) >= -32768 && INTVAL (RTX) <= 32767 ? 2 \
+ : 3; \
+ case CONST: \
+ case LABEL_REF: \
+ case SYMBOL_REF: \
+ return 3; \
+ case CONST_DOUBLE: \
+ return pj_standard_float_constant (RTX) ? 1 : 4; \
+
+/* Like `CONST_COSTS' but applies to nonconstant RTL expressions.
+ This can be used, for example, to indicate how costly a multiply
+ instruction is. In writing this macro, you can use the construct
+ `COSTS_N_INSNS (N)' to specify a cost equal to N fast
+ instructions. OUTER_CODE is the code of the expression in which X
+ is contained. */
+
+#define RTX_COSTS(X,CODE,OUTER_CODE) \
+ case MULT: \
+ if (GET_CODE (XEXP (X, 1)) == CONST_INT) \
+ { \
+ unsigned HOST_WIDE_INT value = INTVAL (XEXP (X, 1)); \
+ int nbits = 0; \
+ \
+ while (value != 0) \
+ { \
+ nbits++; \
+ value >>= 1; \
+ } \
+ \
+ total = COSTS_N_INSNS (nbits); \
+ } \
+ else \
+ total = COSTS_N_INSNS (10); \
+ break;
+
+/* Compute extra cost of moving data between one register class and
+ another. */
+
+#define REGISTER_MOVE_COST(SRC_CLASS, DST_CLASS) \
+ ((SRC_CLASS == STD_REGS || SRC_CLASS == ARG_REGS)? 2 : 10)
+
+
+/* Assembler output control. */
+
+/* A C string constant describing how to begin a comment in the target
+ assembler language. The compiler assumes that the comment will end at
+ the end of the line. */
+#define ASM_COMMENT_START "!"
+
+/* The text to go at the start of the assembler file. */
+
+#undef ASM_FILE_START
+#define ASM_FILE_START(FILE) \
+ fprintf (FILE,"\t.file\t\"%s\"\n", main_input_filename); \
+ fprintf (FILE,"\t! %s\n", TARGET_LITTLE_ENDIAN ? ".little" : ".big"); \
+ fprintf (FILE,"\t.align 4\n");
+
+#define ASM_LONG ".long"
+#define ASM_APP_ON ""
+#define ASM_APP_OFF ""
+#define FILE_ASM_OP "\t.file\n"
+
+#define SET_ASM_OP ".set"
+
+/* How to change between sections. */
+
+#define TEXT_SECTION_ASM_OP "\t.text"
+#define DATA_SECTION_ASM_OP "\t.data"
+
+/* This special macro is used to output the asm pseduo op which allows
+ the linker to fixup broken calling conentions. */
+
+#define ASM_OUTPUT_FUNCTION_PREFIX(FILE, FNNAME) \
+do { fputs (current_function_varargs || current_function_stdarg \
+ ? "\t.varargs_words_needed\t" : "\t.words_needed\t", \
+ FILE); \
+ assemble_name (FILE, FNNAME); \
+ fprintf (FILE, ", %d\n", current_function_args_info.named_words); \
+ } while (0)
+
+/* If defined, a C expression whose value is a string containing the
+ assembler operation to identify the following data as
+ uninitialized G data. If not defined, and neither
+ `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
+ uninitialized global data will be output in the data section if
+ `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
+ used. */
+
+#define BSS_SECTION_ASM_OP ".section\t.bss"
+
+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a
+ separate, explicit argument. If you define this macro, it is used
+ in place of `ASM_OUTPUT_BSS', and gives you more flexibility in
+ handling the required alignment of the variable. The alignment is
+ specified as the number of bits.
+
+ Try to use function `asm_output_aligned_bss' defined in file
+ `varasm.c' when defining this macro. */
+
+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
+ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
+
+
+/* Define this so that jump tables go in same section as the current function,
+ which could be text or it could be a user defined section. */
+#define JUMP_TABLES_IN_TEXT_SECTION 1
+
+/* The assembler's names for the registers. */
+
+#define REGISTER_NAMES \
+{ \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14","r15", \
+ "r16","r17", "r18", "r19", "r20", "r21", "r22","r23", \
+ "r24","r25", "r26", "r27", "r28", "r29", "r30","r31", \
+ \
+ "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7", \
+ "i8", "i9", "i10", "i11", "i12", "i13", "i14","i15", \
+ "i16","i17", "i18", "i19", "i20", "i21", "i22","i23", \
+ "i24","i25", "i26", "i27", "i28", "i29", "i30","i31", \
+ \
+ "global0", "global1", "global2", "global3", \
+ "global4", "global5", "global6", "global7", \
+ "vars", "optop", "sc", "pc", \
+ "ticks", "slow", "va", "d3", \
+ "d4", "d5", "d6", "ap", \
+ "p0", "p1", "p2", "p3", \
+ "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", \
+ \
+ "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7", \
+ "o8", "o9", "o10", "o11", "o12", "o13", "o14","o15", \
+ "o16","o17", "o18", "o19", "o20", "o21", "o22","o23", \
+ "o24","o25", "o26", "o27", "o28", "o29", "o30","o31"} \
+
+
+/* Output a label definition. */
+
+#define ASM_OUTPUT_LABEL(FILE,NAME) \
+ do { assemble_name ((FILE), (NAME)); fputs (":\n", (FILE)); } while (0)
+
+/* This is how to output an assembler line
+ that says to advance the location counter
+ to a multiple of 2**LOG bytes. */
+
+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
+ if ((LOG) != 0) \
+ fprintf ((FILE), "\t.align %d\n", (LOG))
+
+/* Output a globalising directive for a label. */
+
+#define ASM_GLOBALIZE_LABEL(STREAM,NAME) \
+ (fprintf ((STREAM), "\t.global\t"), \
+ assemble_name ((STREAM), (NAME)), \
+ fputc ('\n', (STREAM)))
+
+/* After an opcode has been printed, there's nothing on the line any
+ more. */
+
+#define ASM_OUTPUT_OPCODE(STREAM, P) \
+ pj_stuff_on_line = 0;
+
+/* The prefix to add to user-visible assembler symbols. */
+
+//#define USER_LABEL_PREFIX ""
+
+/* The prefix to add to an internally generated label. */
+
+//#define LOCAL_LABEL_PREFIX ""
+
+/* Construct a private name. */
+
+#define ASM_FORMAT_PRIVATE_NAME(OUTVAR,NAME,NUMBER) \
+ ((OUTVAR) = (char *) alloca (strlen (NAME) + 10), \
+ sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)))
+
+/* Output a relative address table. */
+
+#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM,BODY,VALUE,REL) \
+ asm_fprintf ((STREAM), "\t.long\t.L%d-.L%di\n", (VALUE),(REL));
+
+#define ADDR_VEC_ALIGN(VEC) 0
+
+/* Output various types of constants. */
+
+/* This is how to output an assembler line defining a `double'. */
+
+#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
+do { char dstr[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr); \
+ fprintf ((FILE), "\t.double %s\n", dstr); \
+ } while (0)
+
+/* This is how to output an assembler line defining a `float' constant. */
+
+#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
+do { char dstr[30]; \
+ REAL_VALUE_TO_DECIMAL ((VALUE), "%.20e", dstr); \
+ fprintf ((FILE), "\t.float %s\n", dstr); \
+ } while (0)
+
+#define ASM_OUTPUT_INT(STREAM, EXP) \
+ (fprintf ((STREAM), "\t.long\t"), \
+ output_addr_const ((STREAM), (EXP)), \
+ fputc ('\n', (STREAM)))
+
+#define ASM_OUTPUT_SHORT(STREAM, EXP) \
+ (fprintf ((STREAM), "\t.short\t"), \
+ output_addr_const ((STREAM), (EXP)), \
+ fputc ('\n', (STREAM)))
+
+#define ASM_OUTPUT_CHAR(STREAM, EXP) \
+ (fprintf ((STREAM), "\t.byte\t"), \
+ output_addr_const ((STREAM), (EXP)), \
+ fputc ('\n', (STREAM)))
+
+#define ASM_OUTPUT_BYTE(STREAM, VALUE) \
+ fprintf ((STREAM), "\t.byte\t%d\n", (VALUE))
+
+/* This says how to output an assembler line
+ to define a global common symbol. */
+
+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
+( fputs ("\t.comm ", (FILE)), \
+ assemble_name ((FILE), (NAME)), \
+ fprintf ((FILE), ",%d\n", (SIZE)))
+
+/* This says how to output an assembler line
+ to define a local common symbol. */
+
+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
+( fputs ("\t.lcomm ", (FILE)), \
+ assemble_name ((FILE), (NAME)), \
+ fprintf ((FILE), ",%d\n", (SIZE)))
+
+/* The assembler's parentheses characters. */
+#define ASM_OPEN_PAREN "("
+#define ASM_CLOSE_PAREN ")"
+
+/* We don't want the default switch handling. */
+#undef ASM_OUTPUT_BEFORE_CASE_LABEL
+#undef ASM_OUTPUT_CASE_LABEL
+
+/* Target characters. */
+#define TARGET_BELL 007
+#define TARGET_BS 010
+#define TARGET_TAB 011
+#define TARGET_NEWLINE 012
+#define TARGET_VT 013
+#define TARGET_FF 014
+#define TARGET_CR 015
+
+/* Print operand X (an rtx) in assembler syntax to file FILE.
+ CODE is a letter or star or 0 if no letter was specified.
+ For `%' followed by punctuation, CODE is the punctuation and X is null. */
+
+#define PRINT_OPERAND(STREAM, X, CODE) pj_print_operand ((STREAM), (X), (CODE))
+
+/* Print a memory address as an operand to reference that memory location. */
+
+#define PRINT_OPERAND_ADDRESS(STREAM,X) output_addr_const (STREAM, X)
+
+/* Punctuation valid for print_operand. */
+
+#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '*')
+
+
+/* Define this macro if it is advisable to hold scalars in registers
+ in a wider mode than that declared by the program. In such cases,
+ the value is constrained to be within the bounds of the declared
+ type, but kept valid in the wider mode. The signedness of the
+ extension may differ from that of the type.
+
+ Since picoJava doesn't have unsigned compares, prefer signed
+ arithmetic. */
+
+#define PROMOTE_MODE(MODE, UNSIGNEDP, TYPE) \
+ if (GET_MODE_CLASS (MODE) == MODE_INT \
+ && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
+ { \
+ (MODE) = SImode; \
+ (UNSIGNEDP) = 0; \
+ }
+
+/* Defining PROMOTE_FUNCTION_ARGS eliminates some unnecessary zero/sign
+ extensions applied to char/short functions arguments. Defining
+ PROMOTE_FUNCTION_RETURN does the same for function returns. */
+#define PROMOTE_FUNCTION_ARGS
+
+/* For the sake of libgcc2.c, indicate target supports atexit. */
+#define HAVE_ATEXIT
+
+
+/* We can debug without a frame pointer. */
+#define CAN_DEBUG_WITHOUT_FP
+
+/* How to renumber registers for dbx and gdb. */
+extern short pj_debugreg_renumber_vec[];
+
+#define DBX_REGISTER_NUMBER(REG) (pj_debugreg_renumber_vec[REG])
+
+#define DONT_USE_BUILTIN_SETJMP
+
+/* We prefer to use dwarf2. */
+#undef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+#define DWARF2_UNWIND_INFO 1
+#define DWARF_LINE_MIN_INSTR_LENGTH 1
+
+
+/* varargs and stdarg builtins. */
+
+#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \
+do { \
+ tree t = build (MODIFY_EXPR, TREE_TYPE (valist), valist, \
+ make_tree (ptr_type_node, gen_rtx_REG (Pmode, VA_REG))); \
+ TREE_SIDE_EFFECTS (t) = 1; \
+ expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); \
+ } while (0)
+
+
+#define EXPAND_BUILTIN_VA_ARG(valist, type) \
+ pj_expand_builtin_va_arg(valist, type)
+
+#define EXPAND_BUILTIN_NEXT_ARG(OFFSET) \
+ gen_rtx_MEM (Pmode, \
+ plus_constant (gen_rtx_REG (SImode, VARS_REG), \
+ (INTVAL (offset) + 1) * -4));
+
+/* Before the prologue, the return address is just above optop. */
+#define INCOMING_RETURN_ADDR_RTX \
+ plus_constant (gen_rtx_REG (Pmode, OPTOP_REG), 4)
+
+/* Use thunks for vtables. */
+#define DEFAULT_VTABLE_THUNKS 1
+
+/* Rewrite the rtl to use take advantage of the opstack. */
+#define MACHINE_DEPENDENT_REORG(INSNS) pj_machine_dependent_reorg(INSNS)
+
+
+/* Define the codes that are matched by predicates in pj.c. */
+#define PREDICATE_CODES \
+ {"pj_dest_operand", {SUBREG, REG, MEM,}}, \
+ {"pj_signed_comparison_operator", {EQ, NE, LE, LT, GE, GT}}, \
+ {"pj_unsigned_comparison_operator", {LEU, LTU, GEU, GTU}}, \
+ {"pj_source_operand", {CONST_INT, CONST_DOUBLE, CONST, \
+ SYMBOL_REF, LABEL_REF, SUBREG, \
+ REG, MEM}},
+
+/* Generate calls to memcpy, memcmp and memset. */
+#define TARGET_MEM_FUNCTIONS
diff --git a/gcc/config/pj/pj.md b/gcc/config/pj/pj.md
new file mode 100644
index 0000000..f5a3054
--- /dev/null
+++ b/gcc/config/pj/pj.md
@@ -0,0 +1,991 @@
+;; Machine description for GNU compiler, picoJava Version
+;; Copyright (C) 2000 Free Software Foundation, Inc.
+;; Contributed by Steve Chamberlain, of Transmeta (sac@pobox.com).
+
+;; This file is part of GNU CC.
+
+;; GNU CC 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 1, or (at your option)
+;; any later version.
+
+;; GNU CC 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 GNU CC; see the file COPYING. If not, write to
+;; the Free Software Foundation, 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;; Move instructions.
+
+(define_insn "movsi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (match_operand:SI 1 "pj_source_operand" "gS"))]
+ ""
+ "%S1%R0")
+
+(define_insn "movhi"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=gD")
+ (match_operand:HI 1 "pj_source_operand" "gS"))]
+ ""
+ "%S1%R0")
+
+(define_insn "movqi"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=gD")
+ (match_operand:QI 1 "pj_source_operand" "gS"))]
+ ""
+ "%S1%R0")
+
+(define_insn "movdi"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (match_operand:DI 1 "pj_source_operand" "gS"))]
+ ""
+ "%D1%*%R0")
+
+(define_insn "movdf"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=gD")
+ (match_operand:DF 1 "pj_source_operand" "gS"))]
+ ""
+ "%D1%R0")
+
+(define_insn "movsf"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=gD")
+ (match_operand:SF 1 "pj_source_operand" "gS"))]
+ ""
+ "%S1%R0")
+
+
+;; Arithmetic.
+
+(define_insn "addsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (plus:SI (match_operand:SI 1 "pj_source_operand" "%gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "* return pj_output_addsi3 (operands);")
+
+(define_insn "adddi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (plus:DI (match_operand:DI 1 "pj_source_operand" "%gS")
+ (match_operand:DI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*ladd%R0")
+
+(define_insn "addsf3"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=gD")
+ (plus:SF (match_operand:SF 1 "pj_source_operand" "%gS")
+ (match_operand:SF 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*fadd%R0")
+
+(define_insn "adddf3"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=gD")
+ (plus:DF (match_operand:DF 1 "pj_source_operand" "%gS")
+ (match_operand:DF 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*dadd%R0")
+
+(define_insn "negsi2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (neg:SI (match_operand:SI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*ineg%R0")
+
+(define_insn "negdi2"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (neg:DI (match_operand:DI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*lneg%R0")
+
+(define_insn "negsf2"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=gD")
+ (neg:SF (match_operand:SF 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*fneg%R0")
+
+(define_insn "negdf2"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=gD")
+ (neg:DF (match_operand:DF 1 "pj_source_operand" "gS")))]
+ ""
+ "%D1%*dneg%R0")
+
+(define_insn "subsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (minus:SI (match_operand:SI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*isub%R0")
+
+(define_insn "subdi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (minus:DI (match_operand:DI 1 "pj_source_operand" "gS")
+ (match_operand:DI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*lsub%R0")
+
+(define_insn "subsf3"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=gD")
+ (minus:SF (match_operand:SF 1 "pj_source_operand" "gS")
+ (match_operand:SF 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*fsub%R0")
+
+(define_insn "subdf3"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=gD")
+ (minus:DF (match_operand:DF 1 "pj_source_operand" "gS")
+ (match_operand:DF 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*dsub%R0")
+
+(define_insn "divsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (div:SI (match_operand:SI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*idiv%R0")
+
+(define_insn "divdi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (div:DI (match_operand:DI 1 "pj_source_operand" "gS")
+ (match_operand:DI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*ldiv%R0")
+
+(define_insn "divsf3"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=gD")
+ (div:SF (match_operand:SF 1 "pj_source_operand" "gS")
+ (match_operand:SF 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*fdiv%R0")
+
+(define_insn "divdf3"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=gD")
+ (div:DF (match_operand:DF 1 "pj_source_operand" "gS")
+ (match_operand:DF 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*ddiv%R0")
+
+(define_insn "udivsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (udiv:SI (match_operand:SI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%P1%P2%*ldiv%*l2i%R0")
+
+(define_insn "mulsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (mult:SI (match_operand:SI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*imul%R0")
+
+(define_insn "muldi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (mult:DI (match_operand:DI 1 "pj_source_operand" "gS")
+ (match_operand:DI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*lmul%R0")
+
+(define_insn "muldf3"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=gD")
+ (mult:DF (match_operand:DF 1 "pj_source_operand" "%gS")
+ (match_operand:DF 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*dmul%R0")
+
+(define_insn "mulsf3"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=gD")
+ (mult:SF (match_operand:SF 1 "pj_source_operand" "%gS")
+ (match_operand:SF 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*fmul%R0")
+
+(define_insn "modsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (mod:SI (match_operand:SI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*irem%R0")
+
+(define_insn "moddi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (mod:DI (match_operand:DI 1 "pj_source_operand" "gS")
+ (match_operand:DI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*lrem%R0")
+
+(define_insn "moddf3"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=gD")
+ (mod:DF (match_operand:DF 1 "pj_source_operand" "gS")
+ (match_operand:DF 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*drem%R0")
+
+(define_insn "modsf3"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=gD")
+ (mod:SF (match_operand:SF 1 "pj_source_operand" "gS")
+ (match_operand:SF 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*frem%R0")
+
+(define_insn "umodsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (umod:SI (match_operand:SI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%P1%P2%*lrem%*l2i%R0")
+
+
+;; Logical operations.
+
+(define_insn "andsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (and:SI (match_operand:SI 1 "pj_source_operand" "%gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*iand%R0")
+
+(define_insn "anddi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (and:DI (match_operand:DI 1 "pj_source_operand" "%gS")
+ (match_operand:DI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*land%R0")
+
+(define_insn "iorsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (ior:SI (match_operand:SI 1 "pj_source_operand" "%gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*ior%R0")
+
+(define_insn "iordi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (ior:DI (match_operand:DI 1 "pj_source_operand" "%gS")
+ (match_operand:DI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*lor%R0")
+
+(define_insn "xorsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (xor:SI (match_operand:SI 1 "pj_source_operand" "%gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*ixor%R0")
+
+(define_insn "xordi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (xor:DI (match_operand:DI 1 "pj_source_operand" "%gS")
+ (match_operand:DI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%D2%*lxor%R0")
+
+(define_insn "one_cmplsi2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (not:SI (match_operand:SI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*iconst_m1%*ixor%R0")
+
+(define_insn "one_cmpldi2"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (not:DI (match_operand:DI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*iconst_m1%*iconst_m1%*lxor%R0")
+
+
+;; Shift instructions.
+
+(define_insn "ashlsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (ashift:SI (match_operand:SI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*ishl%R0")
+
+
+(define_insn "ashldi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (ashift:DI (match_operand:DI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%S2%*lshl%R0")
+
+(define_insn "ashrsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (ashiftrt:SI (match_operand:SI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*ishr%R0")
+
+(define_insn "ashrdi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (ashiftrt:DI (match_operand:DI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%S2%*lshr%R0")
+
+(define_insn "lshrsi3"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (lshiftrt:SI (match_operand:SI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%S1%S2%*iushr%R0")
+
+(define_insn "lshrdi3"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (lshiftrt:DI (match_operand:DI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "pj_source_operand" "gS")))]
+ ""
+ "%D1%S2%*lushr%R0")
+
+
+;; Comparisons.
+
+(define_expand "cmpsi"
+ [(set (cc0) (compare (match_operand:SI 0 "pj_source_operand" "gS")
+ (match_operand:SI 1 "pj_source_operand" "gS")))]
+ ""
+ "{
+ pj_cmp_op0 = operands[0];
+ pj_cmp_op1 = operands[1];
+ pj_cmp_mode = SImode;
+ DONE;
+ }")
+
+(define_expand "cmpdi"
+ [(set (cc0) (compare (match_operand:DI 0 "pj_source_operand" "gS")
+ (match_operand:DI 1 "pj_source_operand" "gS")))]
+ ""
+ "{
+ pj_cmp_op0 = operands[0];
+ pj_cmp_op1 = operands[1];
+ pj_cmp_mode = DImode;
+ DONE;
+ }")
+
+(define_expand "cmpsf"
+ [(set (cc0) (compare (match_operand:SF 0 "pj_source_operand" "gS")
+ (match_operand:SF 1 "pj_source_operand" "gS")))]
+ ""
+ "{
+ pj_cmp_op0 = operands[0];
+ pj_cmp_op1 = operands[1];
+ pj_cmp_mode = SFmode;
+ DONE;
+ }")
+
+(define_expand "cmpdf"
+ [(set (cc0) (compare (match_operand:DF 0 "pj_source_operand" "gS")
+ (match_operand:DF 1 "pj_source_operand" "gS")))]
+ ""
+ "{
+ pj_cmp_op0 = operands[0];
+ pj_cmp_op1 = operands[1];
+ pj_cmp_mode = DFmode;
+ DONE;
+ }")
+
+
+;; Conversions.
+
+(define_insn "truncsiqi2"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=gD")
+ (truncate:QI (match_operand:SI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*%R0")
+
+(define_insn "truncsihi2"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=gD")
+ (truncate:HI (match_operand:SI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*i2c%R0")
+
+(define_insn "truncdisi2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (truncate:SI (match_operand:DI 1 "pj_source_operand" "gS")))]
+ ""
+ "%D1%*l2i%R0")
+
+(define_insn "fix_truncsfsi2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (fix:SI (match_operand:SF 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*f2i%R0")
+
+(define_insn "fix_truncsfdi2"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (fix:DI (match_operand:SF 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*f2l%R0")
+
+(define_insn "truncdfsf2"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=gD")
+ (float_truncate:SF (match_operand:DF 1 "pj_source_operand" "gS")))]
+ ""
+ "%D1%*d2f%R0")
+
+(define_insn "fix_truncdfsi2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (fix:SI (match_operand:DF 1 "pj_source_operand" "gS")))]
+ ""
+ "%D1%*d2i%R0")
+
+(define_insn "fix_truncdfdi2"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (fix:DI (match_operand:DF 1 "pj_source_operand" "gS")))]
+ ""
+ "%D1%*d2l%R0")
+
+(define_insn "floatsisf2"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=gD")
+ (float:SF (match_operand:SI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*i2f%R0")
+
+(define_insn "floatsidf2"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=gD")
+ (float:DF (match_operand:SI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*i2d%R0")
+
+(define_insn "floatdisf2"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=gD")
+ (float:SF (match_operand:DI 1 "pj_source_operand" "gS")))]
+ ""
+ "%D1%*l2f%R0")
+
+(define_insn "floatdidf2"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=gD")
+ (float:DF (match_operand:DI 1 "pj_source_operand" "gS")))]
+ ""
+ "%D1%*l2d%R0")
+
+
+;; Zero-extend move instructions.
+
+(define_insn "zero_extendsidi2"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (zero_extend:DI (match_operand:SI 1 "pj_source_operand" "gS")))]
+ ""
+ "%P1%R0")
+
+(define_insn "zero_extendhisi2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (zero_extend:SI (match_operand:HI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*i2c%R0")
+
+(define_insn "zero_extendqisi2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (zero_extend:SI (match_operand:QI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*sipush 0xff%*iand%R0")
+
+
+;; Conditional branch instructions.
+
+(define_expand "beq"
+ [(set (pc) (if_then_else (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "operands[3] = gen_rtx (EQ, pj_cmp_mode);
+ operands[1] = pj_cmp_op0;
+ operands[2] = pj_cmp_op1;")
+
+(define_expand "bne"
+ [(set (pc) (if_then_else (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "operands[3] = gen_rtx (NE, pj_cmp_mode);
+ operands[1] = pj_cmp_op0;
+ operands[2] = pj_cmp_op1;")
+
+(define_expand "bgt"
+ [(set (pc) (if_then_else (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "operands[3] = gen_rtx (GT, pj_cmp_mode);
+ operands[1] = pj_cmp_op0;
+ operands[2] = pj_cmp_op1;")
+
+(define_expand "blt"
+ [(set (pc) (if_then_else (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "operands[3] = gen_rtx (LT, pj_cmp_mode);
+ operands[1] = pj_cmp_op0;
+ operands[2] = pj_cmp_op1;")
+
+(define_expand "bge"
+ [(set (pc) (if_then_else (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "operands[3] = gen_rtx (GE, pj_cmp_mode);
+ operands[1] = pj_cmp_op0;
+ operands[2] = pj_cmp_op1;")
+
+(define_expand "ble"
+ [(set (pc) (if_then_else (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "operands[3] = gen_rtx (LE, pj_cmp_mode);
+ operands[1] = pj_cmp_op0;
+ operands[2] = pj_cmp_op1;")
+
+(define_expand "bgtu"
+ [(set (pc) (if_then_else (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "operands[3] = gen_rtx (GTU, pj_cmp_mode);
+ operands[1] = pj_cmp_op0;
+ operands[2] = pj_cmp_op1;")
+
+(define_expand "bltu"
+ [(set (pc) (if_then_else (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "operands[3] = gen_rtx (LTU, pj_cmp_mode);
+ operands[1] = pj_cmp_op0;
+ operands[2] = pj_cmp_op1;")
+
+(define_expand "bgeu"
+ [(set (pc) (if_then_else (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "operands[3] = gen_rtx (GEU, pj_cmp_mode);
+ operands[1] = pj_cmp_op0;
+ operands[2] = pj_cmp_op1;")
+
+(define_expand "bleu"
+ [(set (pc) (if_then_else (match_op_dup 3 [(match_dup 1) (match_dup 2)])
+ (label_ref (match_operand 0 "" ""))
+ (pc)))]
+ ""
+ "operands[3] = gen_rtx (LEU, pj_cmp_mode);
+ operands[1] = pj_cmp_op0;
+ operands[2] = pj_cmp_op1;")
+
+(define_insn "*bop"
+ [(set (pc) (if_then_else (match_operand:SI 0 "pj_source_operand" "gS")
+ (label_ref (match_operand 1 "" ""))
+ (pc)))]
+ ""
+ "%S0%*ifne %1")
+
+(define_insn "*rev_bop"
+ [(set (pc) (if_then_else (match_operand:SI 0 "pj_source_operand" "gS")
+ (pc)
+ (label_ref (match_operand 1 "" ""))))]
+
+ ""
+ "%S0%*ifeq %1")
+
+(define_insn "*blopsi"
+ [(set (pc)
+ (if_then_else
+ (match_operator:SI 3 "pj_signed_comparison_operator"
+ [(match_operand:SI 0 "pj_source_operand" "gS,gS")
+ (match_operand:SI 1 "pj_source_operand" "K,gS")])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ ""
+ "@
+ %S0%*if%Y3 %2
+ %S0%S1%*if_icmp%Y3 %2")
+
+(define_insn "*rev_blopsi"
+ [(set (pc)
+ (if_then_else
+ (match_operator:SI 3 "pj_signed_comparison_operator"
+ [(match_operand:SI 0 "pj_source_operand" "gS,gS")
+ (match_operand:SI 1 "pj_source_operand" "K,gS")])
+ (pc)
+ (label_ref (match_operand 2 "" ""))))]
+ ""
+ "@
+ %S0%*if%Z3 %2
+ %S0%S1%*if_icmp%Z3 %2")
+
+(define_insn "*bluopsi"
+ [(set (pc)
+ (if_then_else
+ (match_operator:SI 3 "pj_unsigned_comparison_operator"
+ [(match_operand:SI 0 "pj_source_operand" "gS")
+ (match_operand:SI 1 "pj_source_operand" "gS")])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ ""
+ "%S0%S1%*iucmp%*if%Y3 %2")
+
+(define_insn "*rev_bluopsi"
+ [(set (pc)
+ (if_then_else
+ (match_operator:SI 3 "pj_unsigned_comparison_operator"
+ [(match_operand:SI 0 "pj_source_operand" "gS")
+ (match_operand:SI 1 "pj_source_operand" "gS")])
+ (pc)
+ (label_ref (match_operand 2 "" ""))))]
+ ""
+ "%S0%S1%*iucmp%*if%Z3 %2")
+
+(define_insn "*blopdi"
+ [(set (pc)
+ (if_then_else
+ (match_operator:DI 3 "pj_signed_comparison_operator"
+ [(match_operand:DI 0 "pj_source_operand" "gS")
+ (match_operand:DI 1 "pj_source_operand" "gS")])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ ""
+ "%D0%D1%*lcmp%*if%Y3 %2")
+
+(define_insn "*rev_blopdi"
+ [(set (pc)
+ (if_then_else
+ (match_operator:DI 3 "pj_signed_comparison_operator"
+ [(match_operand:DI 0 "pj_source_operand" "gS")
+ (match_operand:DI 1 "pj_source_operand" "gS")])
+ (pc)
+ (label_ref (match_operand 2 "" ""))))]
+ ""
+ "%D0%D1%*lcmp%*if%Z3 %2")
+
+(define_insn "*bluopdi"
+ [(set (pc)
+ (if_then_else
+ (match_operator:DI 3 "pj_unsigned_comparison_operator"
+ [(match_operand:DI 0 "pj_source_operand" "gS")
+ (match_operand:DI 1 "pj_source_operand" "gS")])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ ""
+ "%D0%D1%*ipush __pjucmpdi2%*bipush 6%*call%*if%Y3 %2")
+
+(define_insn "*rev_bluopdi"
+ [(set (pc)
+ (if_then_else
+ (match_operator:DI 3 "pj_unsigned_comparison_operator"
+ [(match_operand:DI 0 "pj_source_operand" "gS")
+ (match_operand:DI 1 "pj_source_operand" "gS")])
+ (pc)
+ (label_ref (match_operand 2 "" ""))))]
+ ""
+ "%D0%D1%*ipush __pjucmpdi2%*bipush 6%*call%*if%Z3 %2")
+
+(define_insn "*blopsf"
+ [(set (pc)
+ (if_then_else
+ (match_operator:SF 3 "comparison_operator"
+ [(match_operand:SF 0 "pj_source_operand" "gS")
+ (match_operand:SF 1 "pj_source_operand" "gS")])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ ""
+ "%S0%S1%*fcmp%X3%*if%Y3 %2")
+
+(define_insn "*rev_bluopsf"
+ [(set (pc)
+ (if_then_else
+ (match_operator:SF 3 "comparison_operator"
+ [(match_operand:SF 0 "pj_source_operand" "gS")
+ (match_operand:SF 1 "pj_source_operand" "gS")])
+ (pc)
+ (label_ref (match_operand 2 "" ""))))]
+ ""
+ "%S0%S1%*fcmp%X3%*if%Z3 %2")
+
+(define_insn "*blopdf"
+ [(set (pc)
+ (if_then_else
+ (match_operator:DF 3 "comparison_operator"
+ [(match_operand:DF 0 "pj_source_operand" "gS")
+ (match_operand:DF 1 "pj_source_operand" "gS")])
+ (label_ref (match_operand 2 "" ""))
+ (pc)))]
+ ""
+ "%D0%D1%*dcmp%X3%*if%Y3 %2")
+
+(define_insn "*rev_bluopdf"
+ [(set (pc)
+ (if_then_else
+ (match_operator:DF 3 "comparison_operator"
+ [(match_operand:DF 0 "pj_source_operand" "gS")
+ (match_operand:DF 1 "pj_source_operand" "gS")])
+ (pc)
+ (label_ref (match_operand 2 "" ""))))]
+ ""
+ "%D0%D1%*dcmp%X3%*if%Z3 %2")
+
+
+;; call instructions
+
+(define_insn "pj_call"
+ [(call (mem:QI (match_operand:SI 0 "pj_source_operand" "gS"))
+ (match_operand:SI 1 "immediate_operand" "i"))]
+ ""
+ "%C0%E1%S0%S1%*call")
+
+(define_insn "pj_call_value"
+ [(set (match_operand 0 "nonimmediate_operand" "=gD")
+ (call (mem:QI (match_operand:SI 1 "pj_source_operand" "gS"))
+ (match_operand:SI 2 "immediate_operand" "i")))]
+
+ ""
+ "%C1%E2%S1%S2%*call")
+
+(define_expand "call"
+ [(call (match_operand:SI 0 "pj_source_operand" "gS")
+ (match_operand:SI 1 "immediate_operand" "i"))
+ (use (match_operand:SI 2 "register_operand" "r"))
+ (use (match_operand:SI 3 "" ""))]
+ ""
+ "{
+ emit_call_insn (gen_pj_call (XEXP (operands[0], 0),
+ pj_workout_arg_words (operands[1],
+ operands[2])));
+ DONE;
+ }")
+
+(define_expand "call_value"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "gS")
+ (call (match_operand:SI 1 "pj_source_operand" "gS")
+ (match_operand:SI 2 "immediate_operand" "i")))
+ (use (match_operand:SI 3 "register_operand" "r"))
+ (use (match_operand:SI 4 "" ""))]
+ ""
+ "{
+ emit_call_insn (gen_pj_call_value (operands[0],
+ XEXP (operands[1], 0),
+ pj_workout_arg_words (operands[2],
+ operands[3])));
+ DONE;
+ }")
+
+
+;; No-op instruction.
+
+(define_insn "nop"
+ [(const_int 0)]
+ ""
+ "nop")
+
+
+;; Jump instructions
+
+(define_insn "jump"
+ [(set (pc) (label_ref (match_operand 0 "" "")))]
+ ""
+ "%*goto %l0")
+
+(define_insn "indirect_jump"
+ [(set (pc) (match_operand:SI 0 "pj_source_operand" "gS"))]
+ ""
+ "%S0%*write_pc")
+
+(define_insn "casesi"
+ [(set (pc)
+ (if_then_else
+ (leu (minus:SI (match_operand:SI 0 "pj_source_operand" "gS")
+ (match_operand:SI 1 "immediate_operand" "i"))
+ (match_operand:SI 2 "immediate_operand" "i"))
+ (plus:SI (sign_extend:SI
+ (mem:SI
+ (plus:SI (pc)
+ (mult:SI (minus:SI (match_dup 0)
+ (match_dup 1))
+ (const_int 4)))))
+ (label_ref (match_operand 3 "" "")))
+ (label_ref (match_operand 4 "" ""))))]
+ ""
+ "%S0\\n%3i:%*tableswitch\\n\\t%*.align 2%*.long %4-%3i%*.long %1%*.long %1+%2")
+
+;; Sign-extend move instructions.
+
+(define_insn "extendsfdf2"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=gD")
+ (float_extend:DF (match_operand:SF 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*f2d%R0")
+
+(define_insn "extendhisi2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (sign_extend:SI (match_operand:HI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*bipush 16%*ishl%*bipush 16%*ishr%R0")
+
+(define_insn "extendqisi2"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (sign_extend:SI (match_operand:QI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*bipush 24%*ishl%*bipush 24%*ishr%R0")
+
+(define_insn "extendqihi2"
+ [(set (match_operand:HI 0 "nonimmediate_operand" "=gD")
+ (sign_extend:HI (match_operand:QI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*bipush 24%*ishl%*bipush 24%*ishr%R0")
+
+(define_insn "extendsidi2"
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=gD")
+ (sign_extend:DI (match_operand:SI 1 "pj_source_operand" "gS")))]
+ ""
+ "%S1%*i2l%R0")
+
+
+;; non local control flow.
+
+(define_expand "save_stack_nonlocal"
+ [(set (match_operand 0 "nonimmediate_operand" "=gD")
+ (match_operand 1 "pj_source_operand" "gS"))]
+ ""
+ "{
+ rtx reg = force_reg (Pmode, XEXP (operands[0], 0));
+ rtx addr0 = gen_rtx_MEM (SImode,reg);
+ rtx addr1 = gen_rtx_MEM (SImode, gen_rtx_PRE_INC (SImode, reg));
+ rtx addr2 = gen_rtx_MEM (SImode, gen_rtx_PRE_INC (SImode, reg));
+
+ emit_move_insn (addr0, gen_rtx_REG (SImode, 64));
+ emit_move_insn (addr1, gen_rtx_REG (SImode, 72));
+ emit_move_insn (addr2, gen_rtx_REG (SImode, 73));
+
+ DONE;
+ }")
+
+(define_insn "restore_stack_nonlocal_helper"
+ [(set (reg:SI 64) (mem:SI (match_operand:SI 0 "register_operand" "r")))
+ (set (reg:SI 72) (mem:SI (pre_inc:SI (match_dup 0))))
+ (set (reg:SI 73) (mem:SI (pre_inc:SI (match_dup 0))))]
+ ""
+ "%S0%*load_word%*write_global0%*iinc %J0,4%S0%*load_word%*iinc %J0,4%S0%*load_word%*write_vars%*write_optop")
+
+(define_expand "restore_stack_nonlocal"
+ [(set (match_operand 0 "nonimmediate_operand" "=gD")
+ (match_operand 1 "pj_source_operand" "gS"))]
+ ""
+ "{
+ rtx reg = force_reg (Pmode, XEXP (operands[1], 0));
+ emit_insn (gen_restore_stack_nonlocal_helper (reg));
+ DONE;
+ }")
+
+(define_insn "nonlocal_goto_helper"
+ [(set (reg:SI 64) (mem:SI (match_operand:SI 0 "register_operand" "r")))
+ (set (reg:SI 72) (mem:SI (pre_inc:SI (match_dup 0))))
+ (set (reg:SI 73) (mem:SI (pre_inc:SI (match_dup 0))))
+ (set (pc) (match_operand:SI 1 "pj_source_operand" "gS"))]
+ ""
+ "%S0%*load_word%*write_global0%*iinc %J0,4%*%S0%*load_word%*%S1%*iinc %J0,4%*%S0%*load_word%*iinc %J0,4%*write_vars%*return0")
+
+(define_expand "nonlocal_goto"
+ [(match_operand:SI 0 "pj_source_operand" "")
+ (match_operand:SI 1 "pj_source_operand" "")
+ (match_operand:SI 2 "pj_source_operand" "")
+ (match_operand:SI 3 "" "")]
+ ""
+ "{
+ rtx addr;
+ rtx temp;
+ emit_move_insn (hard_frame_pointer_rtx, operands[0]);
+
+ temp = copy_to_reg (replace_rtx (operands[1],
+ virtual_stack_vars_rtx,
+ hard_frame_pointer_rtx));
+
+ addr = replace_rtx (copy_rtx (operands[2]),
+ virtual_stack_vars_rtx,
+ hard_frame_pointer_rtx);
+
+ emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));
+ emit_insn (gen_nonlocal_goto_helper (force_reg (Pmode, XEXP (addr, 0)),
+ temp));
+ emit_barrier ();
+ DONE;
+ }")
+
+;; Function overhead.
+
+(define_expand "prologue"
+ [(const_int 0)]
+ ""
+ "pj_expand_prologue (); DONE;")
+
+(define_expand "epilogue"
+ [(return)]
+ ""
+ "pj_expand_epilogue();")
+
+(define_insn "return"
+ [(return)]
+ "reload_completed"
+ "%*return0")
+
+(define_insn "tm_frame"
+ [(use (match_operand:SI 0 "pj_source_operand" "gS"))
+ (set (reg:SI 73)
+ (minus:SI (reg:SI 73)
+ (mult:SI (match_operand:SI 1 "pj_source_operand" "gS")
+ (const_int 4))))]
+
+ ""
+ "%S0%S1%*tm_frame")
+
+(define_insn "varargs"
+ [(unspec_volatile [(match_operand:SI 0 "pj_source_operand" "gS")] 10)]
+ ""
+ "%S0%*jsr_w __vhelper")
+
+(define_insn "varargs_finish"
+ [(unspec_volatile [(match_operand:SI 0 "pj_source_operand" "gS")] 11)]
+ ""
+ "%*iload %J0%*write_global0")
+
+;; Extensions to picoJava.
+
+(define_insn "strlensi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=g")
+ (unspec:SI [(match_operand:BLK 1 "memory_operand" "gS")
+ (match_operand:QI 2 "pj_source_operand" "gS")
+ (match_operand:SI 3 "immediate_operand" "gS")] 0))
+ (clobber (reg:SI 65))]
+ "TARGET_TM_EXTENSIONS"
+ "%I1%S2%S3%*iconst_0%*write_global1%*tm_strlensi%R0")
+
+(define_insn "movstrsi"
+ [(set (match_operand:BLK 0 "memory_operand" "=gS")
+ (match_operand:BLK 1 "memory_operand" "gS"))
+ (use (match_operand:SI 2 "pj_source_operand" "gS"))
+ (use (match_operand:SI 3 "pj_source_operand" "gS"))
+ (clobber (reg:SI 65))]
+ "TARGET_TM_EXTENSIONS"
+ "%I0%I1%S2%S3%*iconst_0%*write_global1%*tm_movstrsi")
+
+(define_insn "clrstrsi"
+ [(set (match_operand:BLK 0 "memory_operand" "=gS")
+ (const_int 0))
+ (use (match_operand:SI 1 "pj_source_operand" "gS"))
+ (use (match_operand:SI 2 "pj_source_operand" "gS"))
+ (clobber (reg:SI 65))]
+ "TARGET_TM_EXTENSIONS"
+ "%I0%*iconst_0%S1%S2%*iconst_0%*write_global1%*tm_memsetsi")
+
+(define_insn "cmpstrsi"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=gD")
+ (compare:SI (match_operand:BLK 1 "memory_operand" "g")
+ (match_operand:BLK 2 "memory_operand" "g")))
+ (use (match_operand:SI 3 "pj_source_operand" "gS"))
+ (use (match_operand:SI 4 "pj_source_operand" "gS"))
+ (clobber (reg:SI 65))]
+ "TARGET_TM_EXTENSIONS"
+ "%I1%I2%S3%S4%*iconst_0%*write_global1%*tm_cmpstrsi%R0")
diff --git a/gcc/config/pj/pjl.h b/gcc/config/pj/pjl.h
new file mode 100644
index 0000000..dcfe861
--- /dev/null
+++ b/gcc/config/pj/pjl.h
@@ -0,0 +1 @@
+#define TARGET_LITTLE_ENDIAN_DEFAULT 1
diff --git a/gcc/config/pj/t-pj b/gcc/config/pj/t-pj
new file mode 100644
index 0000000..2ba9087
--- /dev/null
+++ b/gcc/config/pj/t-pj
@@ -0,0 +1,9 @@
+CROSS_LIBGCC1 = libgcc1-asm.a
+LIB1ASMSRC = pj/lib1funcs.S
+LIB1ASMFUNCS = vhelper pjucmpdi2
+LIB2FUNCS_EXTRA =
+
+# For svr4 we build crtbegin.o and crtend.o which serve to add begin and
+# end labels to the .ctors and .dtors section when we link using gcc.
+
+EXTRA_PARTS=crtbegin.o crtend.o
diff --git a/gcc/config/pj/xm-pj.h b/gcc/config/pj/xm-pj.h
new file mode 100644
index 0000000..e635cce
--- /dev/null
+++ b/gcc/config/pj/xm-pj.h
@@ -0,0 +1,39 @@
+/* Configuration for GNU C-compiler for picoJava.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC 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.
+
+GNU CC 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 GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* #defines that need visibility everywhere. */
+#define FALSE 0
+#define TRUE 1
+
+/* This describes the machine the compiler is hosted on. */
+#define HOST_BITS_PER_CHAR 8
+#define HOST_BITS_PER_SHORT 16
+#define HOST_BITS_PER_INT 32
+#define HOST_BITS_PER_LONG 32
+#define HOST_BITS_PER_LONGLONG 64
+
+/* Arguments to use with `exit'. */
+#define SUCCESS_EXIT_CODE 0
+#define FATAL_EXIT_CODE 33
+
+/* target machine dependencies.
+ tm.h is a symbolic link to the actual target specific file. */
+
+#include "tm.h"
diff --git a/gcc/configure b/gcc/configure
index e574c46..1c1e178 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -3311,6 +3311,9 @@ for machine in $build $host $target; do
mips*-*-*)
cpu_type=mips
;;
+ pj*-*-*)
+ cpu_type=pj
+ ;;
powerpc*-*-*)
cpu_type=rs6000
;;
@@ -5587,6 +5590,16 @@ for machine in $build $host $target; do
# xmake_file=pyr/x-pyr
# use_collect2=yes
# ;;
+
+ pj*-linux*)
+ tm_file="svr4.h pj/linux.h ${tm_file}"
+ ;;
+ pj-*)
+ ;;
+ pjl-*)
+ tm_file="svr4.h pj/pjl.h ${tm_file}"
+ ;;
+
romp-*-aos*)
use_collect2=yes
;;
@@ -6672,7 +6685,7 @@ fi
echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6
-echo "configure:6665: checking for strerror in -lcposix" >&5
+echo "configure:6689: checking for strerror in -lcposix" >&5
ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -6680,7 +6693,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcposix $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6673 "configure"
+#line 6697 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6691,7 +6704,7 @@ int main() {
strerror()
; return 0; }
EOF
-if { (eval echo configure:6684: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6708: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -6714,12 +6727,12 @@ fi
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:6707: checking for working const" >&5
+echo "configure:6731: checking for working const" >&5
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6712 "configure"
+#line 6736 "configure"
#include "confdefs.h"
int main() {
@@ -6768,7 +6781,7 @@ ccp = (char const *const *) p;
; return 0; }
EOF
-if { (eval echo configure:6761: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6785: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
@@ -6789,21 +6802,21 @@ EOF
fi
echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:6782: checking for inline" >&5
+echo "configure:6806: checking for inline" >&5
if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
cat > conftest.$ac_ext <<EOF
-#line 6789 "configure"
+#line 6813 "configure"
#include "confdefs.h"
int main() {
} $ac_kw foo() {
; return 0; }
EOF
-if { (eval echo configure:6796: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6820: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
else
@@ -6829,12 +6842,12 @@ EOF
esac
echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:6822: checking for off_t" >&5
+echo "configure:6846: checking for off_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6827 "configure"
+#line 6851 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -6862,12 +6875,12 @@ EOF
fi
echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:6855: checking for size_t" >&5
+echo "configure:6879: checking for size_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6860 "configure"
+#line 6884 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -6897,19 +6910,19 @@ fi
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
# for constant arguments. Useless!
echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:6890: checking for working alloca.h" >&5
+echo "configure:6914: checking for working alloca.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6895 "configure"
+#line 6919 "configure"
#include "confdefs.h"
#include <alloca.h>
int main() {
char *p = alloca(2 * sizeof(int));
; return 0; }
EOF
-if { (eval echo configure:6902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6926: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_header_alloca_h=yes
else
@@ -6930,12 +6943,12 @@ EOF
fi
echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:6923: checking for alloca" >&5
+echo "configure:6947: checking for alloca" >&5
if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6928 "configure"
+#line 6952 "configure"
#include "confdefs.h"
#ifdef __GNUC__
@@ -6963,7 +6976,7 @@ int main() {
char *p = (char *) alloca(1);
; return 0; }
EOF
-if { (eval echo configure:6956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:6980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_func_alloca_works=yes
else
@@ -6995,12 +7008,12 @@ EOF
echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:6988: checking whether alloca needs Cray hooks" >&5
+echo "configure:7012: checking whether alloca needs Cray hooks" >&5
if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6993 "configure"
+#line 7017 "configure"
#include "confdefs.h"
#if defined(CRAY) && ! defined(CRAY2)
webecray
@@ -7025,12 +7038,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
if test $ac_cv_os_cray = yes; then
for ac_func in _getb67 GETB67 getb67; do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7018: checking for $ac_func" >&5
+echo "configure:7042: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7023 "configure"
+#line 7047 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7053,7 +7066,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7046: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7070: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -7080,7 +7093,7 @@ done
fi
echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:7073: checking stack direction for C alloca" >&5
+echo "configure:7097: checking stack direction for C alloca" >&5
if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7088,7 +7101,7 @@ else
ac_cv_c_stack_direction=0
else
cat > conftest.$ac_ext <<EOF
-#line 7081 "configure"
+#line 7105 "configure"
#include "confdefs.h"
find_stack_direction ()
{
@@ -7107,7 +7120,7 @@ main ()
exit (find_stack_direction() < 0);
}
EOF
-if { (eval echo configure:7100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7124: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_c_stack_direction=1
else
@@ -7134,17 +7147,17 @@ unistd.h sys/param.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7127: checking for $ac_hdr" >&5
+echo "configure:7151: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7132 "configure"
+#line 7156 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7137: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7161: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -7174,12 +7187,12 @@ done
strdup __argz_count __argz_stringify __argz_next
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7167: checking for $ac_func" >&5
+echo "configure:7191: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7172 "configure"
+#line 7196 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7202,7 +7215,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7195: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7219: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -7231,12 +7244,12 @@ done
for ac_func in stpcpy
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7224: checking for $ac_func" >&5
+echo "configure:7248: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7229 "configure"
+#line 7253 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7259,7 +7272,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7252: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7276: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -7293,19 +7306,19 @@ EOF
if test $ac_cv_header_locale_h = yes; then
echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
-echo "configure:7286: checking for LC_MESSAGES" >&5
+echo "configure:7310: checking for LC_MESSAGES" >&5
if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7291 "configure"
+#line 7315 "configure"
#include "confdefs.h"
#include <locale.h>
int main() {
return LC_MESSAGES
; return 0; }
EOF
-if { (eval echo configure:7298: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7322: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
am_cv_val_LC_MESSAGES=yes
else
@@ -7326,7 +7339,7 @@ EOF
fi
fi
echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
-echo "configure:7319: checking whether NLS is requested" >&5
+echo "configure:7343: checking whether NLS is requested" >&5
# Check whether --enable-nls or --disable-nls was given.
if test "${enable_nls+set}" = set; then
enableval="$enable_nls"
@@ -7346,7 +7359,7 @@ fi
EOF
echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
-echo "configure:7339: checking whether included gettext is requested" >&5
+echo "configure:7363: checking whether included gettext is requested" >&5
# Check whether --with-included-gettext or --without-included-gettext was given.
if test "${with_included_gettext+set}" = set; then
withval="$with_included_gettext"
@@ -7365,17 +7378,17 @@ fi
ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
-echo "configure:7358: checking for libintl.h" >&5
+echo "configure:7382: checking for libintl.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7363 "configure"
+#line 7387 "configure"
#include "confdefs.h"
#include <libintl.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7368: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7392: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -7392,19 +7405,19 @@ fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
-echo "configure:7385: checking for gettext in libc" >&5
+echo "configure:7409: checking for gettext in libc" >&5
if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7390 "configure"
+#line 7414 "configure"
#include "confdefs.h"
#include <libintl.h>
int main() {
return (int) gettext ("")
; return 0; }
EOF
-if { (eval echo configure:7397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7421: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
gt_cv_func_gettext_libc=yes
else
@@ -7420,7 +7433,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
if test "$gt_cv_func_gettext_libc" != "yes"; then
echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
-echo "configure:7413: checking for bindtextdomain in -lintl" >&5
+echo "configure:7437: checking for bindtextdomain in -lintl" >&5
ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -7428,7 +7441,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lintl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7421 "configure"
+#line 7445 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7439,7 +7452,7 @@ int main() {
bindtextdomain()
; return 0; }
EOF
-if { (eval echo configure:7432: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7456: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -7455,12 +7468,12 @@ fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
-echo "configure:7448: checking for gettext in libintl" >&5
+echo "configure:7472: checking for gettext in libintl" >&5
if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6
-echo "configure:7453: checking for gettext in -lintl" >&5
+echo "configure:7477: checking for gettext in -lintl" >&5
ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -7468,7 +7481,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lintl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7461 "configure"
+#line 7485 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7479,7 +7492,7 @@ int main() {
gettext()
; return 0; }
EOF
-if { (eval echo configure:7472: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -7518,7 +7531,7 @@ EOF
# Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7511: checking for $ac_word" >&5
+echo "configure:7535: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7552,12 +7565,12 @@ fi
for ac_func in dcgettext
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7545: checking for $ac_func" >&5
+echo "configure:7569: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7550 "configure"
+#line 7574 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7580,7 +7593,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -7607,7 +7620,7 @@ done
# Extract the first word of "gmsgfmt", so it can be a program name with args.
set dummy gmsgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7600: checking for $ac_word" >&5
+echo "configure:7624: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7643,7 +7656,7 @@ fi
# Extract the first word of "xgettext", so it can be a program name with args.
set dummy xgettext; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7636: checking for $ac_word" >&5
+echo "configure:7660: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7675,7 +7688,7 @@ else
fi
cat > conftest.$ac_ext <<EOF
-#line 7668 "configure"
+#line 7692 "configure"
#include "confdefs.h"
int main() {
@@ -7683,7 +7696,7 @@ extern int _nl_msg_cat_cntr;
return _nl_msg_cat_cntr
; return 0; }
EOF
-if { (eval echo configure:7676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7700: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
CATOBJEXT=.gmo
DATADIRNAME=share
@@ -7706,7 +7719,7 @@ fi
if test "$CATOBJEXT" = "NONE"; then
echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6
-echo "configure:7699: checking whether catgets can be used" >&5
+echo "configure:7723: checking whether catgets can be used" >&5
# Check whether --with-catgets or --without-catgets was given.
if test "${with_catgets+set}" = set; then
withval="$with_catgets"
@@ -7719,7 +7732,7 @@ fi
if test "$nls_cv_use_catgets" = "yes"; then
echo $ac_n "checking for main in -li""... $ac_c" 1>&6
-echo "configure:7712: checking for main in -li" >&5
+echo "configure:7736: checking for main in -li" >&5
ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -7727,14 +7740,14 @@ else
ac_save_LIBS="$LIBS"
LIBS="-li $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7720 "configure"
+#line 7744 "configure"
#include "confdefs.h"
int main() {
main()
; return 0; }
EOF
-if { (eval echo configure:7727: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7751: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -7762,12 +7775,12 @@ else
fi
echo $ac_n "checking for catgets""... $ac_c" 1>&6
-echo "configure:7755: checking for catgets" >&5
+echo "configure:7779: checking for catgets" >&5
if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7760 "configure"
+#line 7784 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char catgets(); below. */
@@ -7790,7 +7803,7 @@ catgets();
; return 0; }
EOF
-if { (eval echo configure:7783: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:7807: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_catgets=yes"
else
@@ -7812,7 +7825,7 @@ EOF
# Extract the first word of "gencat", so it can be a program name with args.
set dummy gencat; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7805: checking for $ac_word" >&5
+echo "configure:7829: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7848,7 +7861,7 @@ fi
# Extract the first word of "gmsgfmt", so it can be a program name with args.
set dummy gmsgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7841: checking for $ac_word" >&5
+echo "configure:7865: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7885,7 +7898,7 @@ fi
# Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7878: checking for $ac_word" >&5
+echo "configure:7902: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7920,7 +7933,7 @@ fi
# Extract the first word of "xgettext", so it can be a program name with args.
set dummy xgettext; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7913: checking for $ac_word" >&5
+echo "configure:7937: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7978,7 +7991,7 @@ fi
# Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7971: checking for $ac_word" >&5
+echo "configure:7995: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8012,7 +8025,7 @@ fi
# Extract the first word of "gmsgfmt", so it can be a program name with args.
set dummy gmsgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8005: checking for $ac_word" >&5
+echo "configure:8029: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8048,7 +8061,7 @@ fi
# Extract the first word of "xgettext", so it can be a program name with args.
set dummy xgettext; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:8041: checking for $ac_word" >&5
+echo "configure:8065: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8141,7 +8154,7 @@ fi
LINGUAS=
else
echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
-echo "configure:8134: checking for catalogs to be installed" >&5
+echo "configure:8158: checking for catalogs to be installed" >&5
NEW_LINGUAS=
for lang in ${LINGUAS=$ALL_LINGUAS}; do
case "$ALL_LINGUAS" in
@@ -8169,17 +8182,17 @@ echo "configure:8134: checking for catalogs to be installed" >&5
if test "$CATOBJEXT" = ".cat"; then
ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
-echo "configure:8162: checking for linux/version.h" >&5
+echo "configure:8186: checking for linux/version.h" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 8167 "configure"
+#line 8191 "configure"
#include "confdefs.h"
#include <linux/version.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8172: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8196: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -8254,7 +8267,7 @@ fi
echo $ac_n "checking whether windows registry support is requested""... $ac_c" 1>&6
-echo "configure:8247: checking whether windows registry support is requested" >&5
+echo "configure:8271: checking whether windows registry support is requested" >&5
if test x$enable_win32_registry != xno; then
cat >> confdefs.h <<\EOF
#define ENABLE_WIN32_REGISTRY 1
@@ -8283,7 +8296,7 @@ esac
if test x$enable_win32_registry != xno; then
echo $ac_n "checking registry key on windows hosts""... $ac_c" 1>&6
-echo "configure:8276: checking registry key on windows hosts" >&5
+echo "configure:8300: checking registry key on windows hosts" >&5
cat >> confdefs.h <<EOF
#define WIN32_REGISTRY_KEY "$gcc_cv_win32_registry_key"
EOF
@@ -8459,7 +8472,7 @@ fi
# Figure out what assembler alignment features are present.
echo $ac_n "checking assembler alignment features""... $ac_c" 1>&6
-echo "configure:8452: checking assembler alignment features" >&5
+echo "configure:8476: checking assembler alignment features" >&5
gcc_cv_as=
gcc_cv_as_alignment_features=
gcc_cv_as_gas_srcdir=`echo $srcdir | sed -e 's,/gcc$,,'`/gas
@@ -8580,7 +8593,7 @@ fi
echo "$ac_t""$gcc_cv_as_alignment_features" 1>&6
echo $ac_n "checking assembler subsection support""... $ac_c" 1>&6
-echo "configure:8573: checking assembler subsection support" >&5
+echo "configure:8597: checking assembler subsection support" >&5
gcc_cv_as_subsections=
if test x$gcc_cv_as != x; then
# Check if we have .subsection
@@ -8622,7 +8635,7 @@ echo "$ac_t""$gcc_cv_as_subsections" 1>&6
case "$target" in
sparc*-*-*)
echo $ac_n "checking assembler .register pseudo-op support""... $ac_c" 1>&6
-echo "configure:8615: checking assembler .register pseudo-op support" >&5
+echo "configure:8639: checking assembler .register pseudo-op support" >&5
if eval "test \"`echo '$''{'gcc_cv_as_register_pseudo_op'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8652,7 +8665,7 @@ EOF
case "$tm_file" in
*64*)
echo $ac_n "checking for 64 bit support in assembler ($gcc_cv_as)""... $ac_c" 1>&6
-echo "configure:8645: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
+echo "configure:8669: checking for 64 bit support in assembler ($gcc_cv_as)" >&5
if eval "test \"`echo '$''{'gcc_cv_as_flags64'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8697,7 +8710,7 @@ EOF
if test "x$gcc_cv_as_flags64" != xno; then
echo $ac_n "checking for assembler offsetable %lo() support""... $ac_c" 1>&6
-echo "configure:8690: checking for assembler offsetable %lo() support" >&5
+echo "configure:8714: checking for assembler offsetable %lo() support" >&5
if eval "test \"`echo '$''{'gcc_cv_as_offsetable_lo10'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8736,7 +8749,7 @@ EOF
i[34567]86-*-*)
echo $ac_n "checking assembler instructions""... $ac_c" 1>&6
-echo "configure:8729: checking assembler instructions" >&5
+echo "configure:8753: checking assembler instructions" >&5
gcc_cv_as_instructions=
if test x$gcc_cv_as != x; then
set "filds fists" "filds mem; fists mem"
diff --git a/gcc/configure.in b/gcc/configure.in
index 2026ad8..80ad395 100644
--- a/gcc/configure.in
+++ b/gcc/configure.in
@@ -513,6 +513,9 @@ changequote([,])dnl
mips*-*-*)
cpu_type=mips
;;
+ pj*-*-*)
+ cpu_type=pj
+ ;;
powerpc*-*-*)
cpu_type=rs6000
;;
@@ -2911,6 +2914,16 @@ changequote([,])dnl
# xmake_file=pyr/x-pyr
# use_collect2=yes
# ;;
+
+ pj*-linux*)
+ tm_file="svr4.h pj/linux.h ${tm_file}"
+ ;;
+ pj-*)
+ ;;
+ pjl-*)
+ tm_file="svr4.h pj/pjl.h ${tm_file}"
+ ;;
+
romp-*-aos*)
use_collect2=yes
;;