home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-12-22 | 61.8 KB | 2,244 lines |
- Newsgroups: gnu.gcc.bug
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!isa.DE!luik
- From: luik@isa.DE (Andreas Luik)
- Subject: jump optimization may create insns with virtual_regs
- Message-ID: <9212221748.AA11922@einstein.isa.de>
- Sender: gnulists@ai.mit.edu
- Organization: GNUs Not Usenet
- Distribution: gnu
- Date: Tue, 22 Dec 1992 19:48:52 GMT
- Approved: bug-gcc@prep.ai.mit.edu
- Lines: 2231
-
- Program: gcc
- Version: 2.3.2
-
- Host: sparc-sun-sunos4.1.3
- Target: own (all that meet some conditions)
- Area: cc1/jump-optimization
-
- Input file: cc.c
-
- int compare (int a, int b)
- {
- if (a >= b)
- if (a == b)
- return (0);
- else
- return (1);
- else
- return (-1);
- }
-
- gcc command: gcc -S -O cc.c
-
- Synopsis: jump optimization may create insns with virtual_regs
-
- Description:
-
- Suppose a target description with the following properties:
-
- 1. no setcc insns
- 2. PUSH_ROUNDING undefined
- 3. BRANCH_COST 1
- 4. no ashiftrt or lshiftrt insn defined, so libcall must be used
-
- Then jump_optimize will convert the insns as follows:
-
- before jump optimization: (file cc.c.rtl):
-
- ;; Function compare
-
- (note 2 0 3 "" NOTE_INSN_DELETED)
-
- (insn 3 2 4 (set (reg/v:SI 20)
- (mem:SI (reg:SI 16))) -1 (nil)
- (expr_list:REG_EQUIV (mem:SI (reg:SI 16))
- (nil)))
-
- (insn 4 3 5 (set (reg/v:SI 21)
- (mem:SI (plus:SI (reg:SI 16)
- (const_int 4)))) -1 (nil)
- (expr_list:REG_EQUIV (mem:SI (plus:SI (reg:SI 16)
- (const_int 4)))
- (nil)))
-
- (note 5 4 6 "" NOTE_INSN_FUNCTION_BEG)
-
- (note 6 5 8 "" NOTE_INSN_DELETED)
-
- (note 8 6 9 "" NOTE_INSN_DELETED)
-
- (insn 9 8 10 (set (cc0)
- (compare (reg/v:SI 20)
- (reg/v:SI 21))) -1 (nil)
- (nil))
-
- (jump_insn 10 9 12 (set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (label_ref 30)
- (pc))) 12 {blt} (nil)
- (nil))
-
- (insn 12 10 13 (set (cc0)
- (compare (reg/v:SI 20)
- (reg/v:SI 21))) -1 (nil)
- (nil))
-
- (jump_insn 13 12 15 (set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (label_ref 21)
- (pc))) 9 {bne} (nil)
- (nil))
-
- (insn 15 13 16 (set (reg/i:SI 1 R1)
- (const_int 0)) -1 (nil)
- (nil))
-
- (insn 16 15 17 (use (reg/i:SI 1 R1)) -1 (nil)
- (nil))
-
- (jump_insn 17 16 18 (set (pc)
- (label_ref 40)) -1 (nil)
- (nil))
-
- (barrier 18 17 19)
-
- (jump_insn 19 18 20 (set (pc)
- (label_ref 27)) -1 (nil)
- (nil))
-
- (barrier 20 19 21)
-
- (code_label 21 20 23 3 "")
-
- (insn 23 21 24 (set (reg/i:SI 1 R1)
- (const_int 1)) -1 (nil)
- (nil))
-
- (insn 24 23 25 (use (reg/i:SI 1 R1)) -1 (nil)
- (nil))
-
- (jump_insn 25 24 26 (set (pc)
- (label_ref 40)) -1 (nil)
- (nil))
-
- (barrier 26 25 27)
-
- (code_label 27 26 28 4 "")
-
- (jump_insn 28 27 29 (set (pc)
- (label_ref 36)) -1 (nil)
- (nil))
-
- (barrier 29 28 30)
-
- (code_label 30 29 32 2 "")
-
- (insn 32 30 33 (set (reg/i:SI 1 R1)
- (const_int -1)) -1 (nil)
- (nil))
-
- (insn 33 32 34 (use (reg/i:SI 1 R1)) -1 (nil)
- (nil))
-
- (jump_insn 34 33 35 (set (pc)
- (label_ref 40)) -1 (nil)
- (nil))
-
- (barrier 35 34 36)
-
- (code_label 36 35 38 5 "")
-
- (note 38 36 40 "" NOTE_INSN_FUNCTION_END)
-
- (code_label 40 38 0 1 "")
-
- after jump optimization (file cc.c.jump):
-
- ;; Function compare
-
- (note 2 0 3 "" NOTE_INSN_DELETED)
-
- (insn 3 2 4 (set (reg/v:SI 20)
- (mem:SI (reg:SI 14 R14))) -1 (nil)
- (expr_list:REG_EQUIV (mem:SI (reg:SI 14 R14))
- (nil)))
-
- (insn 4 3 5 (set (reg/v:SI 21)
- (mem:SI (plus:SI (reg:SI 14 R14)
- (const_int 4)))) -1 (nil)
- (expr_list:REG_EQUIV (mem:SI (plus:SI (reg:SI 14 R14)
- (const_int 4)))
- (nil)))
-
- (note 5 4 6 "" NOTE_INSN_FUNCTION_BEG)
-
- (note 6 5 8 "" NOTE_INSN_DELETED)
-
- (note 8 6 9 "" NOTE_INSN_DELETED)
-
- (insn 9 8 10 (set (cc0)
- (compare (reg/v:SI 20)
- (reg/v:SI 21))) -1 (nil)
- (nil))
-
- (jump_insn 10 9 43 (set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (label_ref 30)
- (pc))) 12 {blt} (nil)
- (nil))
-
- (insn 43 10 44 (set (reg/i:SI 1 R1)
- (const_int 1)) -1 (nil)
- (nil))
-
- (insn 44 43 45 (set (reg:SI 22)
- (xor:SI (reg/v:SI 20)
- (reg/v:SI 21))) -1 (nil)
- (nil))
-
- (insn 45 44 46 (set (reg:SI 23)
- (neg:SI (reg:SI 22))) -1 (nil)
- (nil))
-
- (insn 46 45 47 (set (reg:SI 24)
- (ior:SI (reg:SI 23)
- (reg:SI 22))) -1 (nil)
- (nil))
-
- (insn 47 46 48 (set (reg:SI 15 R15)
- (plus:SI (reg:SI 15 R15)
- (const_int -8))) -1 (nil)
- (insn_list:REG_LIBCALL 53 (nil)))
-
- (insn 48 47 49 (set (mem:SI (reg:SI 19))
- (reg:SI 24)) -1 (nil)
- (nil))
-
- (insn 49 48 51 (set (mem:SI (plus:SI (reg:SI 19)
- (const_int 4)))
- (const_int 31)) -1 (nil)
- (nil))
-
- (call_insn/u 51 49 52 (set (reg:SI 1 R1)
- (call (mem:SI (symbol_ref:SI ("__lshrsi3")))
- (const_int 8))) -1 (nil)
- (nil))
-
- (insn 52 51 53 (set (reg:SI 15 R15)
- (plus:SI (reg:SI 15 R15)
- (const_int 8))) -1 (nil)
- (nil))
-
- (insn 53 52 54 (set (reg:SI 25)
- (reg:SI 1 R1)) -1 (nil)
- (insn_list:REG_RETVAL 47 (expr_list:REG_EQUAL (lshiftrt:SI (reg:SI 24)
- (const_int 31))
- (nil))))
-
- (insn 54 53 25 (set (reg/i:SI 1 R1)
- (reg:SI 25)) -1 (nil)
- (nil))
-
- (jump_insn 25 54 26 (set (pc)
- (label_ref 42)) -1 (nil)
- (nil))
-
- (barrier 26 25 30)
-
- (code_label 30 26 32 2 "")
-
- (insn 32 30 42 (set (reg/i:SI 1 R1)
- (const_int -1)) -1 (nil)
- (nil))
-
- (code_label 42 32 41 6 "")
-
- (insn 41 42 0 (use (reg/i:SI 1 R1)) -1 (nil)
- (nil))
-
- Please note, that insns 48 and 49 use pseudo register 19, that is the
- VIRTUAL_OUTGOING_ARGS_REGNUM (virtual_outgoing_args_rtx) returned by
- push_block() and used by emit_library_call(). As these virtual
- registers are resolved before jump optimization but never afterwards,
- the compiler will crash in the reload phase.
-
- The following traceback shows the function calls down to the
- push_block call returning the virtual registers:
-
- #0 push_block (size=0x16acc0, extra=0, below=0) at expr.c:1557
- #1 0x6e3e0 in emit_library_call (__builtin_va_alist=1521800) at expr.c:2089
- #2 0x8affc in expand_binop (mode=SImode, binoptab=0x174910, op0=0x16be38,
- op1=0x16ad78, target=0x16be38, unsignedp=1, methods=OPTAB_LIB_WIDEN)
- at optabs.c:1078
- #3 0x82920 in expand_shift (code=RSHIFT_EXPR, mode=SImode, shifted=0x16be38,
- amount=0x177148, target=0x16be38, unsignedp=1) at expmed.c:1540
- #4 0x86514 in emit_store_flag (target=0x16bdb0, code=NE, op0=0x16bdb0,
- op1=0x16ac80, mode=SImode, unsignedp=0, normalizep=1) at expmed.c:3027
- #5 0x85fb4 in emit_store_flag (target=0x16bdb0, code=NE, op0=0x16d8c0,
- op1=0x16d920, mode=SImode, unsignedp=0, normalizep=1) at expmed.c:2904
- #6 0xafa94 in jump_optimize (f=0x16d748, cross_jump=0, noop_moves=0,
- after_regscan=1) at jump.c:1095
- #7 0x3a938 in rest_of_compilation (decl=0x177060) at toplev.c:2288
- #8 0x20f88 in finish_function (nested=0) at c-decl.c:6088
- #9 0x896c in yyparse () at c-parse.y:269
- #10 0x39790 in compile_file (name=0xf7fffac2 "../test/cc.c") at toplev.c:1803
- #11 0x3d808 in main (argc=5, argv=0xf7fff9ec, envp=0xf7fffa04) at toplev.c:3285
-
- Reproduce with:
-
- Unshar the following SHAR-file. It contains the following files:
- risc32.md
- risc32.c
- risc32.h
- xm-risc32.h
- cc.c (the test program)
-
- Configure gcc as a cross-compiler with the appropriate links:
- tm.h -> risc32.h
- config.h -> <config file of host> e.g. config/xm-sparc.h
- md -> risc32.md
- tconfig.h -> xm-risc32.h
- aux-output.c -> risc32.c
- hconfig.h -> <config file of host> e.g. config/xm-sparc.h
-
- Build cc1 using "make"
- Try gcc with call.c: "./gcc -B./ -O2 -da -S cc.c"
- Check the dumped insn information.
-
- Fix:
-
- Either the virtual registers must get instantiated again after
- jump optimization using another call to
- instantiate_virtual_regs(current_function_decl, get_insns ()) in
- toplev.c (I tried that, it seems to work), or jump optimization
- should not create library calls (which seems to make sense but may
- need some additional conditions at different places, so I didn't try
- that). Maybe instantiate_virtual_regs() may be called on the
- sequence of insns created by jump_optimize() only.
-
- I finally aviod the problem by defining BRANCH_COST as 0 because then
- jump optimization will not try to replace the jumps with arithmetic
- computations. If you think this is the correct way to avoid the problem,
- the documentation of BRANCH_COST should get updated to describe that.
-
- #!/bin/sh
- # This is a shell archive (produced by shar 3.49)
- # To extract the files from this archive, save it to a file, remove
- # everything above the "!/bin/sh" line above, and type "sh file_name".
- #
- # made 12/21/1992 19:17 UTC by luik@ramses
- # Source directory /tmp/shar
- #
- # existing files will NOT be overwritten unless -c is specified
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 123 -rw-rw-r-- cc.c
- # 14894 -rw-rw-r-- risc32.c
- # 20416 -rw-rw-r-- risc32.h
- # 13802 -rw-rw-r-- risc32.md
- # 1657 -rw-rw-r-- xm-risc32.h
- #
- # ============= cc.c ==============
- if test -f 'cc.c' -a X"$1" != X"-c"; then
- echo 'x - skipping cc.c (File already exists)'
- else
- echo 'x - extracting cc.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'cc.c' &&
- int compare (int a, int b)
- {
- X if (a >= b)
- X if (a == b)
- X return (0);
- X else
- X return (1);
- X else
- X return (-1);
- }
- SHAR_EOF
- chmod 0664 cc.c ||
- echo 'restore of cc.c failed'
- Wc_c="`wc -c < 'cc.c'`"
- test 123 -eq "$Wc_c" ||
- echo 'cc.c: original size 123, current size' "$Wc_c"
- fi
- # ============= risc32.c ==============
- if test -f 'risc32.c' -a X"$1" != X"-c"; then
- echo 'x - skipping risc32.c (File already exists)'
- else
- echo 'x - extracting risc32.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'risc32.c' &&
- /* Subroutines for insn-output.c for IMS RISC32 controller.
- X Copyright (C) 1992 Andreas Luik <luik@isa.de>.
- X
- This file is part of GNU CC.
- X
- 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.
- X
- 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.
- X
- 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
- X
- #include <assert.h>
- #include <stdio.h>
- #include "config.h"
- #include "rtl.h"
- #include "regs.h"
- #include "hard-reg-set.h"
- #include "insn-config.h"
- #include "conditions.h"
- #include "output.h"
- #include "flags.h"
- X
- X
- char *risc32_inline_shift_limit_cp;
- int risc32_inline_shift_limit = 6;
- X
- extern char call_used_regs[];
- X
- X
- X
- /*
- ** const_to_logical_const computes an immediate operand for any of the logical
- ** operations (XOR, OR, AND) of the RISC32. The constant used in the instruction
- ** specifies the number of the bit to be manipulated (the bit is either set
- ** or cleared). The functions returns 0 if the bit_value does not match.
- */
- X
- int const_to_logical_const (bit_value, inst_value)
- int bit_value; /* constant to be checked */
- int *inst_value; /* RETURN: constant to be used in assembler */
- {
- X register int i;
- X register int b;
- X int dummy;
- X
- X if (inst_value == NULL)
- X inst_value = &dummy;
- X
- X for (i = 0, b = 1; i < BITS_PER_WORD; i++, b <<= 1) {
- X if (bit_value == b) {
- X *inst_value = i;
- X return (1);
- X }
- X if (~bit_value == b) {
- X *inst_value = i | (1 << 4);
- X return (1);
- X }
- X }
- X return (0);
- }
- X
- X
- /*
- ** operand_to_logical_operand returns the CONST_INT rtx with the value
- ** const_to_logical_const() of the parameter op if its mode is CONST_INT.
- */
- X
- rtx operand_to_logical_operand (op)
- rtx op;
- {
- X if (GET_CODE (op) == CONST_INT) {
- X int immediate;
- X if (const_to_logical_const (INTVAL (op), &immediate))
- X return (GEN_INT (immediate));
- X abort ();
- X /*NOTREACHED*/
- X }
- X return op;
- }
- X
- X
- X
- /*
- ** notice_update_cc is called by the final phase for each insn (exp is the
- ** insn pattern). It is used to eliminate spurious test and compare insns.
- ** It must set the value1 and value2 fields in cc_status to the rtls
- ** representing the current condition codes settings as well as the flags
- ** field (the flags and cc_status is defined in conditions.h).
- **
- ** Currently only some easy cases are handled:
- ** 1. none of the jump insn change the condition codes
- ** 2. insns that explicitly set CC0 (test and compare) are handled properly
- ** 3. all other insn initialize cc_status.
- **
- ** These cases at least optimize the code generated for case statements.
- */
- X
- void notice_update_cc (exp, insn)
- rtx exp;
- rtx insn;
- {
- X if (GET_CODE (insn) == JUMP_INSN)
- X return;
- X
- X if ((GET_CODE (exp) == SET
- X && GET_CODE (SET_DEST (exp)) == CC0)) {
- X cc_status.flags = 0;
- X cc_status.value1 = XEXP (exp, 0);
- X cc_status.value2 = XEXP (exp, 1);
- X return;
- X }
- X
- X if ((GET_CODE (exp) == PARALLEL
- X && GET_CODE (XVECEXP (exp, 0, 0)) == SET
- X && GET_CODE (XEXP (XVECEXP (exp, 0, 0), 0)) == CC0)) {
- X cc_status.flags = 0;
- X cc_status.value1 = XEXP (XVECEXP (exp, 0, 0), 0);
- X cc_status.value2 = XEXP (XVECEXP (exp, 0, 0), 1);
- X return;
- X }
- X
- X CC_STATUS_INIT;
- }
- X
- X
- X
- /*
- ** initial_frame_pointer_offset computes the offset between the frame pointer
- ** and the stack pointer immediately after the function prologue. It must
- ** add the frame size and the sizes of the registers that must be saved on
- ** the stack.
- */
- X
- int
- initial_frame_pointer_offset ()
- {
- X int regno;
- X int offset = get_frame_size() ;
- X
- X for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- X if (regs_ever_live[regno] && !call_used_regs[regno])
- X if (!(frame_pointer_needed && regno == FRAME_POINTER_REGNUM))
- X offset += UNITS_PER_WORD;
- X
- X return (offset);
- }
- X
- X
- X
- /*
- ** output_function_prologue writes to the file f the assembler statements
- ** for the start of an assembler procedure. It sets up the stack frame,
- ** initializes the frame pointer, saves registers used in the function
- ** and allocates size additional bytes on the stack.
- */
- X
- void
- output_function_prologue (f, size)
- FILE *f;
- int size; /* bytes to allocate on stack */
- {
- X register int regno;
- X int num_saved_regs;
- X
- X assert (size >= 0);
- X if (frame_pointer_needed) {
- X asm_fprintf (f, "\tPUSH\t%0R%s\n", reg_names[FRAME_POINTER_REGNUM]);
- X asm_fprintf (f, "\tMOV\t%0R%s,%0R%s\n",
- X reg_names[FRAME_POINTER_REGNUM],
- X reg_names[STACK_POINTER_REGNUM]);
- X }
- X else {
- X if (size > 16) /* push SP (restore would be too expensive) */
- X asm_fprintf (f, "\tPUSH\t%0R%s\n", reg_names[STACK_POINTER_REGNUM]);
- X }
- X
- X if (size) {
- X if (size <= 16) {
- X asm_fprintf (f, "\tADD\t%0R%s,%0R%s,%0I%d\n",
- X reg_names[STACK_POINTER_REGNUM],
- X reg_names[STACK_POINTER_REGNUM],
- X -size);
- X }
- X else if (size <= 0x8000) {
- X asm_fprintf (f, "\tLDI\t%0R%s,%0I%d\n",
- X reg_names[FUNCTION_VALUE_REGNUM],
- X -size);
- X asm_fprintf (f, "\tADD\t%0R%s,%0R%s,%0R%s\n",
- X reg_names[STACK_POINTER_REGNUM],
- X reg_names[STACK_POINTER_REGNUM],
- X reg_names[FUNCTION_VALUE_REGNUM]);
- X }
- X else
- X error ("too many local variables");
- X }
- X
- X if (TARGET_STACK_CHECK) {
- X /* XXX to be written */
- X }
- X
- X /*
- X ** Save all used registers. Note that the frame pointer register needs
- X ** not to be saved if it is used as a frame pointer.
- X */
- X
- X num_saved_regs = 0;
- X for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
- X if (regs_ever_live[regno] && !call_used_regs[regno])
- X if (!(frame_pointer_needed && regno == FRAME_POINTER_REGNUM)) {
- X num_saved_regs++;
- X asm_fprintf (f, "\tST\t%0R%s,%0R%s,%0I%d\n",
- X reg_names[regno],
- X reg_names[STACK_POINTER_REGNUM],
- X -num_saved_regs);
- X }
- X
- X if (num_saved_regs) /* maximum value = 16 (FIRST_PSEUDO_REGISTER) */
- X asm_fprintf (f, "\tADD\t%0R%s,%0R%s,%0I%d\n",
- X reg_names[STACK_POINTER_REGNUM],
- X reg_names[STACK_POINTER_REGNUM],
- X -num_saved_regs);
- }
- X
- X
- /*
- ** output_function_epilogue writes the asse,bler code to exit from a function
- ** the the assembler file f. It must restore the register values and the
- ** stack pointer to their values when the function was called.
- ** For documentation purposes, this function outputs a comment with "RET".
- ** The "ENDPROC" assembler directive is written by ASM_DECLARE_FUNCTION_SIZE
- ** because there it is easier to get the function name.
- ** Note that this function should not depend on the value of the stack pointer
- ** register (see documentation of EXIT_IGNORE_STACK).
- */
- X
- void
- output_function_epilogue (f, size)
- FILE *f;
- int size; /* same as for output_function_prologue */
- {
- X register int regno;
- X register int nregs; /* number of registers saved on stack */
- X int offset; /* max offset from FP/SP to saved registers */
- X int inc;
- X rtx insn;
- X
- X /*
- X ** If the last insn was a BARRIER, we don't have to write any code. But
- X ** lets output a no-op so that debuggers don't get confused about which
- X ** function the pc is in at this address.
- X */
- X
- X insn = get_last_insn ();
- X if (GET_CODE (insn) == NOTE)
- X insn = prev_nonnote_insn (insn);
- X if (insn && GET_CODE (insn) == BARRIER) {
- X asm_fprintf (f, "\tNOP\n");
- X return;
- X }
- X
- X assert (current_function_pops_args == 0);
- X assert (size >= 0);
- X
- #ifdef FUNCTION_EXTRA_EPILOGUE
- X FUNCTION_EXTRA_EPILOGUE (f, size);
- #endif
- X
- X if (frame_pointer_needed) {
- X nregs = 0; /* get number of saved registers on stack */
- X for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; regno--)
- X if (regs_ever_live[regno] && !call_used_regs[regno])
- X if (!(frame_pointer_needed && regno == FRAME_POINTER_REGNUM))
- X nregs++;
- X
- X offset = nregs + size;
- X
- X for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- X if (regs_ever_live[regno] && !call_used_regs[regno])
- X if (!(regno == FRAME_POINTER_REGNUM)) {
- X if (offset <= 16) { /* may address saved value directly */
- X asm_fprintf (f, "\tLD\t%0R%s,%0R%s,%0I%d\n",
- X reg_names[regno],
- X reg_names[FRAME_POINTER_REGNUM],
- X -offset);
- X }
- X else { /* need to address using index register */
- X assert (offset <= 0x8000);
- X asm_fprintf (f, "\tLDI\t%0R%s,%0I%d\n",
- X reg_names[regno],
- X -offset);
- X asm_fprintf (f, "\tLD\t%0R%s,%0R%s,%0R%s\n",
- X reg_names[regno],
- X reg_names[FRAME_POINTER_REGNUM],
- X reg_names[regno]);
- X }
- X offset--;
- X }
- X
- X asm_fprintf (f, "\tMOV\t%0R%s,%0R%s\n", /* restore stack pointer */
- X reg_names[STACK_POINTER_REGNUM],
- X reg_names[FRAME_POINTER_REGNUM]);
- X asm_fprintf (f, "\tPOP\t%0R%s\n", /* restore frame pointer */
- X reg_names[FRAME_POINTER_REGNUM]);
- X }
- X else {
- X nregs = 0;
- X for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
- X if (regs_ever_live[regno] && !call_used_regs[regno]) {
- X asm_fprintf (f, "\tLD\t%0R%s,%0R%s,%0I%d\n",
- X reg_names[regno],
- X reg_names[STACK_POINTER_REGNUM],
- X nregs);
- X nregs++;
- X }
- X
- X if (size <= 16) { /* restore SP value by adding the offset value */
- X offset = nregs + size; /* maximum offset value is 32 */
- X
- X while (offset > 0) { /* should be executed at most twice */
- X inc = (offset > 16) ? 16 : offset;
- X asm_fprintf (f, "\tSUB\t%0R%s,%0R%s,%0I%d\n",
- X reg_names[STACK_POINTER_REGNUM],
- X reg_names[STACK_POINTER_REGNUM],
- X -inc);
- X offset -= inc;
- X }
- X }
- X else { /* SP was pushed by prologue in this case */
- X asm_fprintf (f, "\tPOP\t%0R%s\n", reg_names[STACK_POINTER_REGNUM]);
- X }
- X }
- X
- X asm_fprintf (f, "\t;;; RET\n");
- }
- X
- X
- /*
- ** A C compound statement to output to stdio stream f the
- ** assembler syntax for an instruction operand op. op is an RTL
- ** expression.
- **
- ** letter is a value that can be used to specify one of several ways
- ** of printing the operand. It is used when identical operands
- ** must be printed differently depending on the context. letter
- ** comes from the `%' specification that was used to request
- ** printing of the operand. If the specification was just `%DIGIT'
- ** then letter is 0; if the specification was `%LTR DIGIT' then letter
- ** is the ASCII letter for LTR.
- **
- ** If op is a register, this macro should print the register's name.
- ** The names can be found in an array `reg_names' whose type is
- ** `char *[]'. `reg_names' is initialized from `REGISTER_NAMES'.
- **
- ** When the machine description has a specification `%PUNCT' (a `%'
- ** followed by a punctuation character), this macro is called with
- ** a null pointer for op and the punctuation character for letter.
- **
- ** The risc32 specific letters are:
- **
- ** '#' for an immediate operand prefix
- ** '%' for a register operand prefix
- */
- X
- void
- print_operand (f, op, letter)
- FILE *f; /* file to write to */
- rtx op; /* operand to print */
- int letter; /* %<letter> or 0 */
- {
- X switch (letter) {
- X case '#':
- X asm_fprintf (f, "%0I");
- X break;
- X
- X case '%':
- X asm_fprintf (f, "%0R");
- X break;
- X
- X default:
- X abort ();
- X /*NOTREACHED*/
- X
- X case 0:
- X switch (GET_CODE (op)) {
- X case REG:
- X asm_fprintf (f, "%0R%s", reg_names[REGNO (op)]);
- X break;
- X
- X case MEM:
- X output_address (XEXP (op, 0));
- X break;
- X
- X case CONST:
- X case CONST_INT:
- X case LABEL_REF:
- X case SYMBOL_REF:
- X asm_fprintf (f, "%0I");
- X output_addr_const (f, op);
- X break;
- X
- X default:
- X fprintf (stderr, "print_operand: unknown code %d\n", GET_CODE (op));
- X abort ();
- X /*NOTREACHED*/
- X }
- X }
- }
- X
- X
- /*
- ** A C compound statement to output to stdio stream f the
- ** assembler syntax for an instruction operand that is a memory
- ** reference whose address is addr. addr is an RTL expression.
- */
- X
- void
- print_operand_address (f, addr)
- FILE *f;
- rtx addr;
- {
- X rtx base;
- X rtx offset = 0;
- X rtx index = 0;
- X
- X switch (GET_CODE (addr)) {
- X case REG:
- X asm_fprintf (f, "%0R%s", reg_names[REGNO (addr)]);
- X break;
- X
- X case PLUS:
- X if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
- X offset = XEXP (addr, 0), base = XEXP (addr, 1);
- X else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
- X offset = XEXP (addr, 1), base = XEXP (addr, 0);
- X else
- X index = XEXP (addr, 1), base = XEXP (addr, 0);
- X
- X asm_fprintf (f, "%0R%s", reg_names [REGNO (base)]);
- X if (index)
- X asm_fprintf (f, ",%0R%s", reg_names [REGNO (index)]);
- X else {
- X assert (((unsigned) INTVAL (offset) + 16) < 32);
- X asm_fprintf (f, ",");
- X output_addr_const (f, offset);
- X }
- X break;
- X
- X case CONST:
- X case CONST_INT:
- X case LABEL_REF:
- X case SYMBOL_REF:
- X output_addr_const (f, addr);
- X break;
- X
- X default:
- X fprintf (stderr, "print_operand_address: unknown code %d\n",
- X GET_CODE (addr));
- X abort ();
- X /*NOTREACHED*/
- X }
- }
- X
- X
- /*
- ** r32_call_operand checks whether op is a legal operand for a RISC32 CALL
- ** instruction. Most call operands are memory references. These are ignored
- ** by calling r32_call_operand recursivly with the first expression of the
- ** memory reference. Legal operands are CONST_INT and SYMBOL_REF.
- ** The mode of the operand is currently ignored. Maybe it should be compared
- ** against FUNCTION_MODE.
- */
- X
- /*ARGSUSED*/
- int r32_call_operand (op, mode)
- rtx op;
- enum machine_mode mode;
- {
- X switch (GET_CODE (op)) {
- X case MEM:
- X return (r32_call_operand (XEXP (op, 0), mode));
- X
- X case CONST_INT:
- X case SYMBOL_REF:
- X return (1);
- X }
- X return (0);
- }
- X
- X
- /*
- ** Function calls to absolute addresses (e.g. ((int (*)()) 0)(arg)) are
- ** converted to a call to a register. The constant is forced to a register
- ** immediately before the expansion of the call insn. To allow such constructs,
- ** the define_expand for a call and a call_value insn checks for register
- ** operands and calls r32_get_reg_value_rtx. This function checks the
- ** previous non-note insn whether it is a set insn with dest = op and a
- ** constant src. This constant is returned if found because it's the current
- ** value of the register used in the call insn. Otherwise 0 is returned and the
- ** define_expand will treat this as an error.
- */
- X
- rtx r32_get_reg_value_rtx (op)
- rtx op;
- {
- X rtx insn;
- X
- X assert (GET_CODE (op) == REG);
- X
- X insn = get_last_insn_anywhere ();
- X while (insn && GET_CODE (insn) == NOTE)
- X insn = previous_insn (insn);
- X
- X if (insn && GET_CODE (insn) == INSN) {
- X rtx pat = PATTERN (insn);
- X if ((GET_CODE (pat) == SET
- X && GET_CODE (SET_DEST (pat)) == REG
- X && REGNO (SET_DEST (pat)) == REGNO (op)
- X && GET_MODE (SET_DEST (pat)) == GET_MODE (op)
- X && CONSTANT_P (SET_SRC (pat))))
- X return (SET_SRC (pat));
- X }
- X
- X return ((rtx) 0);
- }
- X
- SHAR_EOF
- chmod 0664 risc32.c ||
- echo 'restore of risc32.c failed'
- Wc_c="`wc -c < 'risc32.c'`"
- test 14894 -eq "$Wc_c" ||
- echo 'risc32.c: original size 14894, current size' "$Wc_c"
- fi
- # ============= risc32.h ==============
- if test -f 'risc32.h' -a X"$1" != X"-c"; then
- echo 'x - skipping risc32.h (File already exists)'
- else
- echo 'x - extracting risc32.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'risc32.h' &&
- /* Definitions of target machine for GNU compiler, for IMS RISC32 controller.
- X Copyright (C) 1992 Andreas Luik <luik@isa.de>.
- X
- This file is part of GNU CC.
- X
- 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.
- X
- 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.
- X
- 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
- X
- X
- /*
- ** External variables/functions defined in risc32.c.
- */
- X
- extern char *risc32_inline_shift_limit_cp;
- extern int risc32_inline_shift_limit;
- X
- /*
- ** Controlling the Compilation Driver
- ** ----------------------------------
- */
- X
- /* #define SWITCHES_TAKES_ARG(C) */
- /* #define WORD_SWITCH_TAKES_ARG(NAME) */
- /* #define SWITCHES_NEED_SPACES */
- #define CPP_SPEC "%{mbarrel-shifter:-D__HAVE_BARREL_SHIFTER__}"
- /* #define SIGNED_CHAR_SPEC */
- /* #define CC1_SPEC */
- /* #define CC1PLUS_SPEC */
- /* #define ASM_SPEC */
- /* #define ASM_FINAL_SPEC */
- /* #define LINK_SPEC */
- #define LIB_SPEC ""
- #define STARTFILE_SPEC "%{crt0-r32.o%s}"
- /* #define ENDFILE_SPEC */
- /* #define LINK_LIBGCC_SPECIAL */
- /* #define RELATIVE_PREFIX_NOT_LINKDIR */
- /* #define STANDARD_EXEC_PREFIX */
- /* #define STANDARD_STARTFILE_PREFIX */
- X
- X
- /*
- ** Run-time Target Specification
- ** ------------------------------
- */
- X
- #define CPP_PREDEFINES "-Drisc32"
- /* #define STDC_VALUE */
- X
- extern int target_flags;
- X
- #define TARGET_BARREL_SHIFTER (target_flags & 1)
- #define TARGET_STACK_CHECK (target_flags & 2)
- #define TARGET_ABORT_ON_NOT_IMPLEMENTED (target_flags & 4)
- X
- #define TARGET_DEFAULT 0x0
- X
- #define TARGET_SWITCHES { \
- X {"barrel-shifter", 1}, \
- X {"no-barrel-shifter", -1}, \
- X {"stack-check", 2}, \
- X {"no-stack-check", -2}, \
- X {"abort-on-not-implemented", 4}, \
- X {"no-abort-on-not-implemented", -4},\
- X { "", TARGET_DEFAULT}}
- X
- #define TARGET_OPTIONS { \
- X { "inline-shift-limit-", &risc32_inline_shift_limit_cp } }
- X
- #define OVERRIDE_OPTIONS \
- X do { \
- X if (profile_flag) \
- X { \
- X warning ("`-p' option (function profile) not supported"); \
- X profile_flag = 0; \
- X } \
- X if (risc32_inline_shift_limit_cp) \
- X { \
- X int err = FALSE; \
- X int limit; \
- X char *p; \
- X \
- X for (p = risc32_inline_shift_limit_cp; *p && !err; p++) \
- X if (! (*p >= '0' && *p <= '9')) \
- X err = TRUE; \
- X \
- X if ((limit = atoi (risc32_inline_shift_limit_cp)) <= 1) \
- X err = TRUE; \
- X if (!err) \
- X risc32_inline_shift_limit = limit; \
- X else error ("Invalid option value `-minline-shift-limit-%s'", \
- X risc32_inline_shift_limit_cp); \
- X } \
- X } while (0)
- X
- /* Omit frame pointer at high optimization levels. */
- #define OPTIMIZATION_OPTIONS(OPTIMIZE) \
- X do { \
- X if (OPTIMIZE >= 3) \
- X flag_omit_frame_pointer = 1; \
- X } while (0)
- X
- #define TARGET_VERSION \
- X fprintf (stderr, " (IMS RISC32, ASM syntax)");
- X
- X
- /*
- ** Storage Layout
- ** --------------
- */
- X
- /* #define BITS_BIG_ENDIAN */
- #define BYTES_BIG_ENDIAN 1
- #define WORDS_BIG_ENDIAN 1
- X
- #define BITS_PER_UNIT 8
- #define BITS_PER_WORD 32
- #define UNITS_PER_WORD 4
- #define POINTER_SIZE 32
- #define PARM_BOUNDARY 8
- #define FUNCTION_BOUNDARY 8
- #define BIGGEST_ALIGNMENT 8
- #define EMPTY_FIELD_BOUNDARY 8
- #define STRICT_ALIGNMENT 1
- #define MAX_FIXED_MODE_SIZE 32
- /* #define CHECK_FLOAT_VALUE */ /* floats are not supported yet */
- /* #define TARGET_FLOAT_FORMAT */ /* floats are not supported yet */
- X
- /*
- ** Layout of Source Language Data Types
- ** ------------------------------------
- */
- X
- #define INT_TYPE_SIZE BITS_PER_WORD
- #define SHORT_TYPE_SIZE 16
- #define LONG_TYPE_SIZE 32
- #define LONG_LONG_TYPE_SIZE 64
- #define CHAR_TYPE_SIZE BITS_PER_UNIT
- #define FLOAT_TYPE_SIZE 32 /* floats are not supported yet */
- #define DOUBLE_TYPE_SIZE 64 /* floats are not supported yet */
- /* #define LONG_DOUBLE_TYPE_SIZE*/ /* floats are not supported yet */
- X
- #define DEFAULT_SIGNED_CHAR 1
- X
- #define SIZE_TYPE "unsigned int" /* XXX */
- #define PTRDIFF_TYPE "unsigned int" /* XXX */
- #define WCHAR_TYPE "unsigned int" /* XXX */
- #define WCHAR_TYPE_SIZE 32
- X
- #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
- X
- X
- /*
- ** Register Usage
- ** --------------
- */
- X
- #define FIRST_PSEUDO_REGISTER 16
- X
- #define FIXED_REGISTERS \
- X { \
- X 1, 0, 0, 0, 0, 0, 0, 0, \
- X 0, 0, 0, 0, 0, 0, 0, 1, \
- X }
- X
- #define CALL_USED_REGISTERS \
- X { \
- X 1, 1, 1, 1, 1, 0, 0, 0, \
- X 0, 0, 0, 0, 0, 0, 1, 1, \
- X }
- X
- #define HARD_REGNO_NREGS(REGNO, MODE) \
- X ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
- X
- #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
- X
- #define MODES_TIEABLE_P(MODE1,MODE2) 1
- X
- X
- /*
- ** Register Classes
- ** ----------------
- */
- X
- enum reg_class { NO_REGS, GENERAL_REGS, ALL_REGS, LIM_REG_CLASSES };
- X
- #define N_REG_CLASSES (int) LIM_REG_CLASSES
- X
- #define REG_CLASS_NAMES \
- X { "NO_REGS", "GENERAL_REGS", "ALL_REGS" }
- X
- #define REG_CLASS_CONTENTS { \
- X 0x00000000, /* NO_REGS */ \
- X 0x0000fffe, /* GENERAL_REGS */ \
- X 0x0000ffff, /* ALL_REGS */ \
- X }
- X
- #define REGNO_REG_CLASS(REGNO) ((REGNO) == 0 ? ALL_REGS : GENERAL_REGS)
- X
- #define BASE_REG_CLASS GENERAL_REGS
- #define INDEX_REG_CLASS GENERAL_REGS
- X
- #define REG_CLASS_FROM_LETTER(C) NO_REGS
- X
- #define HARD_REGNO_OK_FOR_BASE_OR_INDEX_P(REGNO) \
- X ((REGNO) > 0 && (REGNO) < FIRST_PSEUDO_REGISTER)
- X
- #define REGNO_OK_FOR_BASE_P(REGNO) \
- X (HARD_REGNO_OK_FOR_BASE_OR_INDEX_P(REGNO) \
- X || HARD_REGNO_OK_FOR_BASE_OR_INDEX_P((unsigned) reg_renumber[REGNO]))
- X
- #define REGNO_OK_FOR_INDEX_P(REGNO) \
- X (HARD_REGNO_OK_FOR_BASE_OR_INDEX_P(REGNO) \
- X || HARD_REGNO_OK_FOR_BASE_OR_INDEX_P((unsigned) reg_renumber[REGNO]))
- X
- #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
- X
- #define CLASS_MAX_NREGS(CLASS, MODE) \
- X ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
- X
- /*
- ** special constraint strings:
- ** I ... immediate value -16..15 for NEG/ONE_CMPL/ROT/LSHI/ASHI
- ** J ... immediate value -16..16 for ADD
- ** K ... immediate value with one bit set or cleared for XOR/OR/AND
- */
- X
- #define CONST_OK_FOR_LETTER_P(VALUE,C) \
- X ((C) == 'I' ? ((VALUE) >= -16 && (VALUE) <= 15) : \
- X (C) == 'J' ? ((VALUE) >= -16 && (VALUE) <= 16) : \
- X (C) == 'K' ? const_to_logical_const ((VALUE), (int *) 0) : 0) \
- X
- #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE,C) \
- X 0
- X
- X
- /*
- ** Describing Stack Layout and Calling Conventions
- ** -----------------------------------------------
- */
- X
- #define STACK_GROWS_DOWNWARD
- #define FRAME_GROWS_DOWNWARD
- #define STARTING_FRAME_OFFSET 0
- #define FIRST_PARM_OFFSET(FNDECL) 0
- X
- #define STACK_POINTER_REGNUM 15
- #define FRAME_POINTER_REGNUM 14
- #define ARG_POINTER_REGNUM FRAME_POINTER_REGNUM
- #define STATIC_CHAIN_REGNUM 13
- X
- #define FRAME_POINTER_REQUIRED 0
- X
- #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) \
- X (DEPTH) = initial_frame_pointer_offset ()
- X
- /* #define LONGJMP_RESTORE_FROM_STACK */
- X
- #define PROMOTE_PROTOTYPES
- /* #define PUSH_ROUNDING(BYTES) */ /* we do not use a push instruction */
- #define RETURN_POPS_ARGS(FUNTYPE,SIZE) 0
- X
- #define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) 0
- #define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
- #define CUMULATIVE_ARGS int
- #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \
- X ((CUM) = 0)
- #define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
- X ((CUM) += ((MODE) != BLKmode \
- X ? GET_MODE_SIZE (MODE) \
- X : int_size_in_bytes (TYPE)))
- #define FUNCTION_ARG_REGNO_P(N) 0
- X
- #define FUNCTION_VALUE_REGNUM 1
- #define FUNCTION_VALUE(VALTYPE, FUNC) \
- X gen_rtx (REG, TYPE_MODE (VALTYPE), FUNCTION_VALUE_REGNUM)
- #define LIBCALL_VALUE(MODE) \
- X gen_rtx (REG, MODE, FUNCTION_VALUE_REGNUM)
- #define FUNCTION_VALUE_REGNO_P(N) ((N) == FUNCTION_VALUE_REGNUM)
- X
- #define STRUCT_VALUE_REGNUM 2
- X
- #define FUNCTION_PROLOGUE(FILE, SIZE) output_function_prologue(FILE, SIZE)
- #define EXIT_IGNORE_STACK 1
- #define FUNCTION_EPILOGUE(FILE, SIZE) output_function_epilogue(FILE, SIZE)
- X
- /* FUNCTION_PROFILER is used for -p */
- #define FUNCTION_PROFILER(FILE, LABEL) /* profiling not supported */
- X
- /* Block profiling is enabled with "-a", but this is optional and not supported
- X on the RISC32. */
- /* #define FUNCTION_BLOCK_PROFILER(FILE, LABEL) */
- /* #define BLOCK_PROFILER(FILE, BLOCK) */
- X
- X
- /*
- ** Implementing the Varargs Macro
- ** ------------------------------
- */
- X
- /*
- ** The default varargs macros may be used since we pass parameters on a
- ** stack
- */
- X
- /*
- ** Trampolines for Nested Functions
- ** --------------------------------
- */
- X
- #define TRAMPOLINE_TEMPLATE(FILE) /* trampolines not supported */
- #define TRAMPOLINE_SIZE 0
- #define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) /* trampolines not supported */
- /* #define INSN_CACHE_SIZE */
- /* #define INSN_CACHE_LINE_WIDTH */
- /* #define INSN_CACHE_DEPTH */
- X
- /*
- ** Implicit Calls to Library Routines
- ** ----------------------------------
- */
- X
- /*
- ** Addressing Modes
- ** ----------------
- */
- X
- #define CONSTANT_ADDRESS_P(X) CONSTANT_P(X) /* XXX */
- X
- #define MAX_REGS_PER_ADDRESS 2
- X
- #ifndef REG_OK_STRICT
- # define REG_OK_FOR_INDEX_P(X) FALSE
- # define REG_OK_FOR_BASE_P(X) (REGNO (X) != 0)
- #else
- # define REG_OK_FOR_INDEX_P(X) (REGNO_OK_FOR_INDEX_P (REGNO (X)))
- # define REG_OK_FOR_BASE_P(X) (REGNO_OK_FOR_BASE_P (REGNO (X)))
- #endif
- X
- #define IS_REG_OK_FOR_BASE_P(X) \
- X (REG_P (X) && REG_OK_FOR_BASE_P (X))
- X
- #define GO_IF_CONST_ADDRESS(X, ADDR) \
- X { \
- X if ((CONSTANT_ADDRESS_P (X) || \
- X IS_REG_OK_FOR_BASE_P (X))) \
- X goto ADDR; \
- X }
- X
- #define GO_IF_OFFSET_ADDRESS(X, ADDR) \
- X { \
- X if ((GET_CODE (X) == PLUS && \
- X IS_REG_OK_FOR_BASE_P (XEXP (X, 0)) && \
- X GET_CODE (XEXP (X, 1)) == CONST_INT && \
- X ((unsigned) INTVAL (XEXP (X, 1)) + 16) < 32)) \
- X goto ADDR; \
- X }
- X
- #define GO_IF_INDEX_ADDRESS(X, ADDR) \
- X { \
- X if ((GET_CODE (X) == PLUS && \
- X IS_REG_OK_FOR_BASE_P (XEXP (X, 0)) && \
- X IS_REG_OK_FOR_BASE_P (XEXP (X, 1)))) \
- X goto ADDR; \
- X }
- X
- #define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
- X { \
- X GO_IF_CONST_ADDRESS (X, ADDR); \
- X GO_IF_OFFSET_ADDRESS (X, ADDR); \
- X GO_IF_INDEX_ADDRESS (X, ADDR); \
- X }
- X
- #define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) {}
- #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) {}
- X
- #define LEGITIMATE_CONSTANT_P(X) 1
- X
- X
- /*
- ** Condition Code Status
- ** ---------------------
- */
- X
- #define NOTICE_UPDATE_CC(EXP, INSN) \
- X notice_update_cc(EXP, INSN)
- X
- X
- /*
- ** Describing Relative Costs of Operations
- ** ---------------------------------------
- */
- X
- #define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- X case CONST_INT: \
- X if (((unsigned) INTVAL (RTX)) + 16 < 32) \
- X return 1; \
- X return 2; \
- X case CONST: \
- X case LABEL_REF: \
- X case SYMBOL_REF: \
- X return 1; \
- X case CONST_DOUBLE: \
- X return 8;
- X
- #define RTX_COSTS(X,CODE,OUTER_CODE) \
- X case SIGN_EXTEND: \
- X return (COSTS_N_INSNS (TARGET_BARREL_SHIFTER ? 4 : 5)); \
- X case ASHIFT: \
- X case ASHIFTRT: \
- X case LSHIFT: \
- X case LSHIFTRT: \
- X case ROTATE: \
- X case ROTATERT: \
- X return (COSTS_N_INSNS (TARGET_BARREL_SHIFTER ? 1 : 6)); \
- X case MULT: \
- X return COSTS_N_INSNS (10); /* XXX */ \
- X case DIV: \
- X case UDIV: \
- X case MOD: \
- X case UMOD: \
- X return COSTS_N_INSNS (10); /* XXX */
- X
- #define SLOW_BYTE_ACCESS 0
- #define NO_FUNCTION_CSE
- #define NO_RECURSIVE_FUNCTION_CSE
- X
- X
- /*
- ** Dividing the Output into Sections
- ** ---------------------------------
- */
- X
- #define TEXT_SECTION_ASM_OP ".TEXT"
- #define DATA_SECTION_ASM_OP ".DATA"
- /* #define SHARED_SECTION_ASM_OP */
- /* #define INIT_SECTION_ASM_OP */
- #define READONLY_DATA_SECTION data_section
- X
- X
- /*
- ** Position Independent Code
- ** -------------------------
- */
- X
- /*
- ** it is not possible to implement position independent code on RISC32
- */
- X
- X
- /*
- ** Defining the Output Assembler Language
- ** --------------------------------------
- */
- X
- #define ASM_FILE_START(FILE) \
- X fprintf (FILE, "%s", ASM_APP_OFF); \
- X if (TARGET_BARREL_SHIFTER) \
- X fprintf (FILE, "\tBARREL\n"); \
- X fprintf (FILE, "\tPRG\n");
- X
- /* #define ASM_FILE_END(FILE) */
- X
- #define ASM_IDENTIFY_GCC(FILE) fprintf (FILE, ";gcc2_compiled.:\n");
- X
- #define ASM_COMMENT_START ";"
- X
- #define ASM_APP_ON ";APP\n"
- #define ASM_APP_OFF ";NO_APP\n"
- #define ASM_OUTPUT_SOURCE_FILENAME(FILE,NAME)
- #define ASM_OUTPUT_SOURCE_LINE(FILE,LINE)
- /* #define ASM_OUTPUT_IDENT(FILE,IDENT) */
- #define OBJC_PROLOGUE
- X
- #define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
- X (sorry ("double constants"), \
- X fprintf (FILE, "\t;DOUBLE\t0r%.20g\n", (VALUE)))
- X
- #define ASM_OUTPUT_FLOAT(FILE,VALUE) \
- X (sorry ("float constants"), \
- X fprintf (FILE, "\t;FLOAT\t0r%.20g\n", (VALUE)))
- X
- #define ASM_OUTPUT_SHORT(FILE,VALUE) \
- X (sorry ("initialized variables"), \
- X fprintf (FILE, "\t;WORD\t"), \
- X output_addr_const (FILE, (VALUE)), \
- X fprintf (FILE, "\n"))
- X
- #define ASM_OUTPUT_CHAR(FILE,VALUE) \
- X (sorry ("initialized variables"), \
- X fprintf (FILE, "\t;WORD\t"), \
- X output_addr_const (FILE, (VALUE)), \
- X fprintf (FILE, "\n"))
- X
- /* ASM_BYTE_OP is only used in dwarfout.c and in assemble_zeros() if
- X ASM_NO_SKIP_IN_TEXT == 1. */
- #define ASM_BYTE_OP ";WORD"
- X
- #define ASM_OUTPUT_BYTE(FILE,VALUE) \
- X (sorry ("initialized variables"), \
- X fprintf (FILE, "\t%s\t0x%x\n", ASM_BYTE_OP, (VALUE)))
- X
- #define ASM_OUTPUT_ASCII(FILE,PTR,LEN) \
- X sorry ("string constants");
- X
- #define ASM_OPEN_PAREN "("
- #define ASM_CLOSE_PAREN ")"
- X
- #define ASM_OUTPUT_COMMON(FILE,NAME,SIZE,ROUNDED) \
- X (fprintf (FILE, "\t.GLOBAL\t"), \
- X assemble_name (FILE, (NAME)), \
- X fprintf (FILE, "\n"), \
- X ASM_OUTPUT_LOCAL(FILE,NAME,SIZE,ROUNDED))
- X
- #define ASM_OUTPUT_LOCAL(FILE,NAME,SIZE,ROUNDED) \
- X (fprintf (FILE, "\t.COMMON\t"), \
- X assemble_name (FILE, (NAME)), \
- X fprintf (FILE, ",%u\n",(ROUNDED))) \
- X
- #define ASM_OUTPUT_LABEL(FILE,NAME) \
- X (assemble_name (FILE, NAME), fputs (":\n", FILE))
- X
- #define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
- X (assemble_name (FILE, NAME), fputs ("\tPROC\n", FILE))
- X
- /* ASM_DECLARE_FUNCTION_SIZE is used to output the ENDPROC assembler
- X directive. Alternatively, this may go into output_function_epilogue
- X but getting the function name is more difficult there. */
- #define ASM_DECLARE_FUNCTION_SIZE(FILE,NAME,DECL) \
- X (assemble_name (FILE, NAME), fputs ("\tENDPROC\n", FILE))
- X
- /* #define ASM_DECLARE_OBJECT_NAME(FILE,NAME,DECL) */
- X
- #define ASM_GLOBALIZE_LABEL(FILE,NAME) \
- X (fprintf (FILE, "\t.EXPORT\t"), \
- X assemble_name (FILE, (NAME)), \
- X fprintf (FILE, "\n"))
- X
- /* #define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME) */
- /* #define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE,SYMREF) */
- X
- #define ASM_OUTPUT_LABELREF(FILE,NAME) \
- X asm_fprintf (FILE, "%U%s", NAME)
- X
- /* #define ASM_OUTPUT_LABELREF_AS_INT(FILE,LABEL) */
- X
- #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- X asm_fprintf (FILE, "%0L%s%d:\n", PREFIX, NUM)
- X
- #define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
- X sprintf (LABEL, "*%s%s%d", LOCAL_LABEL_PREFIX, PREFIX, NUM)
- X
- #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
- X ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
- X sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
- X
- /* #include "aoutos.h" */
- X
- #define REGISTER_NAMES { \
- X "R0", "R1", "R2", "R3", "R4", "R5" , "R6", "R7", \
- X "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15" }
- X
- #define ADDITIONAL_REGISTER_NAMES { \
- X { "FP", 14 }, \
- X { "SP", 15 } }
- X
- /* #define ASM_OUTPUT_OPCODE(FILE,CP) */
- X
- #define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
- X
- #define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == '#' || (CODE) == '%')
- X
- #define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
- X
- #define REGISTER_PREFIX "" /* used for %R in asm_fprintf */
- #define LOCAL_LABEL_PREFIX "" /* used for %L in asm_fprintf */
- #define USER_LABEL_PREFIX "_" /* used for %U in asm_fprintf */
- #define IMMEDIATE_PREFIX "" /* used for %I in asm_fprintf */
- X
- /* The next two macros (reg PUSH and POP) are only used for profiling which
- X is currently unsupported. */
- #define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
- X asm_fprintf (FILE, "\tPUSH\t%0R%s\n", reg_names[REGNO]);
- X
- #define ASM_OUTPUT_REG_POP(FILE,REGNO) \
- X asm_fprintf (FILE, "\tPOP\t%0R%s\n", reg_names[REGNO]);
- X
- /* Code for dispatch tables is not required because we use an (nearly)
- X infinite CASE_VALUES_THRESHOLD. */
- #define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) abort ()
- #define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) abort ()
- X
- #define ASM_OUTPUT_SKIP(FILE,BYTES) \
- X { \
- X int i = (BYTES); \
- X if (in_text_section ()) { \
- X while (i--) \
- X asm_fprintf (FILE, "\tNOP\t; skip one byte (contents zero)\n"); \
- X } \
- X else { \
- X while (i--) \
- X ASM_OUTPUT_BYTE (FILE, 0); \
- X } \
- X }
- X
- #define ASM_NO_SKIP_IN_TEXT 0
- X
- #define ASM_OUTPUT_ALIGN(FILE,POWER) abort ();
- X
- /*
- ** Controlling Debbuging Information Format
- ** ----------------------------------------
- */
- X
- /*
- ** Debugging informations are not supported yet. Currently no debugger is
- ** available.
- */
- X
- #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
- X
- X
- /*
- ** Cross Compilation and Floating Point Format
- ** -------------------------------------------
- */
- X
- /*
- ** No floating point format was definied for the risc32 yet, so we leave this
- ** section empty.
- */
- X
- X
- /*
- ** Miscellaneous Parameters
- ** ------------------------
- */
- X
- #define CASE_VECTOR_MODE SImode
- #define CASE_VALUES_THRESHOLD 32767
- #define EASY_DIV_EXPR TRUNC_DIV_EXPR
- #define MOVE_MAX 1
- #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
- #define STORE_FLAG_VALUE -1 /* XXX */
- #define Pmode SImode
- #define FUNCTION_MODE SImode
- X
- X
- /*
- ** Declare functions defined in risc32.c and used in templates.
- */
- X
- SHAR_EOF
- chmod 0664 risc32.h ||
- echo 'restore of risc32.h failed'
- Wc_c="`wc -c < 'risc32.h'`"
- test 20416 -eq "$Wc_c" ||
- echo 'risc32.h: original size 20416, current size' "$Wc_c"
- fi
- # ============= risc32.md ==============
- if test -f 'risc32.md' -a X"$1" != X"-c"; then
- echo 'x - skipping risc32.md (File already exists)'
- else
- echo 'x - extracting risc32.md (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'risc32.md' &&
- ;;- Machine description for GNU compiler
- ;;- IMS RISC32 controler Version
- ;; Copyright (C) 1992 Andreas Luik <luik@isa.de>.
- X
- ;; This file is part of GNU CC.
- X
- ;; 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.
- X
- ;; 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.
- X
- ;; 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, 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- X
- ;;
- ;; Test and compare operations (PSW operations)
- ;; --------------------------------------------
- ;;
- X
- (define_insn "tstsi"
- X [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
- X ""
- X "TST %0")
- X
- (define_insn "cmpsi"
- X [(set (cc0) (compare (match_operand:SI 0 "register_operand" "r")
- X (match_operand:SI 1 "register_operand" "r")))]
- X ""
- X "CMP %0,%1")
- X
- X
- ;;
- ;; Unconditional jumps
- ;; -------------------
- ;;
- X
- (define_insn "jump"
- X [(set (pc) (label_ref (match_operand 0 "" "")))]
- X ""
- X "JMP %l0")
- X
- (define_insn "indirect_jump"
- X [(set (pc) (match_operand:SI 0 "general_operand" "r"))]
- X ""
- X "*
- {
- X sorry (\"computed goto or goto to non-local label\");
- X return \"JMP %0\";
- }")
- X
- ;;
- ;; Subroutine handling and stack operations
- ;; ----------------------------------------
- ;;
- X
- (define_expand "call"
- X [(call (mem:SI (match_operand:SI 0 "" ""))
- X (match_operand 1 "" ""))]
- X ""
- X "
- {
- X rtx op0; /* operand0 without (mem ()) */
- X extern rtx r32_get_reg_value_rtx ();
- X
- X op0 = GET_CODE (operands[0]) == MEM ? XEXP (operands[0], 0) : operands[0];
- X if (GET_CODE (op0) == REG) {
- X rtx value = r32_get_reg_value_rtx (op0); /* search for register value */
- X if (value) /* value of register found, use it */
- X op0 = value;
- X }
- X
- X if (!r32_call_operand (op0, SImode)) {
- X sorry (\"pointers to functions\");
- X if (TARGET_ABORT_ON_NOT_IMPLEMENTED)
- X abort ();
- X op0 = gen_rtx (SYMBOL_REF, SImode, \"unknown\");
- X }
- X
- X operands[0] = op0; /* (mem ()) added by RTL template */
- }")
- X
- (define_insn ""
- X [(call (match_operand:SI 0 "r32_call_operand" "m")
- X (match_operand 1 "general_operand" "g"))]
- X ;; Operand 1 not really used on the risc32.
- X ""
- X "CALL %0")
- X
- X
- (define_expand "call_value"
- X [(set (match_operand 0 "" "=r")
- X (call (mem:SI (match_operand:SI 1 "" ""))
- X (match_operand 2 "" "")))]
- X ""
- X "
- {
- X rtx op1; /* operand1 without (mem ()) */
- X extern rtx r32_get_reg_value_rtx ();
- X
- X op1 = GET_CODE (operands[1]) == MEM ? XEXP (operands[1], 0) : operands[1];
- X if (GET_CODE (op1) == REG) {
- X rtx value = r32_get_reg_value_rtx (op1); /* search for register value */
- X if (value) /* value of register found, use it */
- X op1 = value;
- X }
- X
- X if (!r32_call_operand (op1, SImode)) {
- X sorry (\"pointers to functions\");
- X if (TARGET_ABORT_ON_NOT_IMPLEMENTED)
- X abort ();
- X op1 = gen_rtx (SYMBOL_REF, SImode, \"unknown\");
- X }
- X
- X operands[1] = op1; /* (mem ()) added by RTL template */
- }")
- X
- (define_insn ""
- X [(set (match_operand 0 "" "=r")
- X (call (match_operand:SI 1 "r32_call_operand" "m")
- X (match_operand 2 "general_operand" "g")))]
- X ;; Operand 2 not really used on the risc32.
- X ""
- X "CALL %1")
- X
- X
- ;;
- ;; Conditional jumps
- ;; -----------------
- ;;
- X
- (define_insn "beq"
- X [(set (pc) (if_then_else (eq (cc0) (const_int 0))
- X (label_ref (match_operand 0 "" ""))
- X (pc)))]
- X ""
- X "JEQ %l0")
- X
- (define_insn "bne"
- X [(set (pc) (if_then_else (ne (cc0) (const_int 0))
- X (label_ref (match_operand 0 "" ""))
- X (pc)))]
- X ""
- X "JNE %l0")
- X
- (define_insn "bgt"
- X [(set (pc) (if_then_else (gt (cc0) (const_int 0))
- X (label_ref (match_operand 0 "" ""))
- X (pc)))]
- X ""
- X "JGT %l0")
- X
- (define_insn "bgtu"
- X [(set (pc) (if_then_else (gtu (cc0) (const_int 0))
- X (label_ref (match_operand 0 "" ""))
- X (pc)))]
- X ""
- X "JHI %l0")
- X
- (define_insn "blt"
- X [(set (pc) (if_then_else (lt (cc0) (const_int 0))
- X (label_ref (match_operand 0 "" ""))
- X (pc)))]
- X ""
- X "JLT %l0")
- X
- (define_insn "bltu"
- X [(set (pc) (if_then_else (ltu (cc0) (const_int 0))
- X (label_ref (match_operand 0 "" ""))
- X (pc)))]
- X ""
- X "JLO %l0")
- X
- (define_insn "bge"
- X [(set (pc) (if_then_else (ge (cc0) (const_int 0))
- X (label_ref (match_operand 0 "" ""))
- X (pc)))]
- X ""
- X "JGE %l0")
- X
- (define_insn "bgeu"
- X [(set (pc) (if_then_else (geu (cc0) (const_int 0))
- X (label_ref (match_operand 0 "" ""))
- X (pc)))]
- X ""
- X "JHS %l0")
- X
- (define_insn "ble"
- X [(set (pc) (if_then_else (le (cc0) (const_int 0))
- X (label_ref (match_operand 0 "" ""))
- X (pc)))]
- X ""
- X "JLE %l0")
- X
- (define_insn "bleu"
- X [(set (pc) (if_then_else (leu (cc0) (const_int 0))
- X (label_ref (match_operand 0 "" ""))
- X (pc)))]
- X ""
- X "JLS %l0")
- X
- ;; reverse-conditional branches
- X
- (define_insn ""
- X [(set (pc) (if_then_else (eq (cc0) (const_int 0))
- X (pc)
- X (label_ref (match_operand 0 "" ""))))]
- X ""
- X "JNE %l0")
- X
- (define_insn ""
- X [(set (pc) (if_then_else (ne (cc0) (const_int 0))
- X (pc)
- X (label_ref (match_operand 0 "" ""))))]
- X ""
- X "JEQ %l0")
- X
- (define_insn ""
- X [(set (pc) (if_then_else (gt (cc0) (const_int 0))
- X (pc)
- X (label_ref (match_operand 0 "" ""))))]
- X ""
- X "JLE %l0")
- X
- (define_insn ""
- X [(set (pc) (if_then_else (gtu (cc0) (const_int 0))
- X (pc)
- X (label_ref (match_operand 0 "" ""))))]
- X ""
- X "JLS %l0")
- X
- (define_insn ""
- X [(set (pc) (if_then_else (lt (cc0) (const_int 0))
- X (pc)
- X (label_ref (match_operand 0 "" ""))))]
- X ""
- X "JGE %l0")
- X
- (define_insn ""
- X [(set (pc) (if_then_else (ltu (cc0) (const_int 0))
- X (pc)
- X (label_ref (match_operand 0 "" ""))))]
- X ""
- X "JHS %l0")
- X
- (define_insn ""
- X [(set (pc) (if_then_else (ge (cc0) (const_int 0))
- X (pc)
- X (label_ref (match_operand 0 "" ""))))]
- X ""
- X "JLT %l0")
- X
- (define_insn ""
- X [(set (pc) (if_then_else (geu (cc0) (const_int 0))
- X (pc)
- X (label_ref (match_operand 0 "" ""))))]
- X ""
- X "JLO %l0")
- X
- (define_insn ""
- X [(set (pc) (if_then_else (le (cc0) (const_int 0))
- X (pc)
- X (label_ref (match_operand 0 "" ""))))]
- X ""
- X "JGT %l0")
- X
- (define_insn ""
- X [(set (pc) (if_then_else (leu (cc0) (const_int 0))
- X (pc)
- X (label_ref (match_operand 0 "" ""))))]
- X ""
- X "JHI %l0")
- X
- X
- ;;
- ;; Load and Store operations
- ;; -------------------------
- ;;
- X
- (define_insn "movsi"
- X [(set (match_operand:SI 0 "general_operand" "=r,r,r,o")
- X (match_operand:SI 1 "general_operand" "r,o,i,r"))]
- X ""
- X "*
- {
- X switch (which_alternative) {
- X case 0:
- X return \"MOV %0,%1\";
- X
- X case 1: /* operands[1] must have code MEM */
- X switch (GET_CODE (XEXP (operands[1], 0))) {
- X case SYMBOL_REF:
- X return \"LDA %0,%1\";
- X case REG:
- X return \"LD %0,%1,%#0\";
- X default:
- X return \"LD %0,%1\";
- X }
- X
- X case 2:
- X if (INTVAL (operands[1]) == 0)
- X return \"CLR %0\";
- X else
- X return \"LDI %0,%1\";
- X
- X case 3: /* operands[0] must have code MEM */
- X switch (GET_CODE (XEXP (operands[0], 0))) {
- X case SYMBOL_REF:
- X return \"STA %1,%0\";
- X case REG:
- X return \"ST %1,%0,%#0\";
- X default:
- X return \"ST %1,%0\";
- X }
- X
- X default:
- X abort ();
- X /*NOTREACHED*/
- X };
- }")
- X
- ;;
- ;; Arithmetic operations
- ;; ---------------------
- ;;
- X
- (define_insn "addsi3"
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (plus:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "rJ")))]
- X ""
- X "*
- {
- X if (GET_CODE (operands[2]) == CONST_INT) {
- X int value = INTVAL (operands[2]);
- X
- X /*
- X ** Use SUB instead of ADD for negative constants. Note that
- X ** addition of the constant 16 is converted to subtraction of
- X ** -16 (this saves one instruction because 16 is too big for
- X ** an immediate add operand).
- X */
- X
- X if (value == 16 || (value > -16 && value < 0)) {
- X operands[2] = GEN_INT (-value);
- X return \"SUB %0,%1,%2\";
- X }
- X }
- X
- X return \"ADD %0,%1,%2\";
- }")
- X
- (define_insn "subsi3"
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (minus:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "register_operand" "r")))]
- X ""
- X "SUB %0,%1,%2")
- X
- ;;
- ;; Logical operations
- ;; ------------------
- ;;
- X
- (define_insn "andsi3"
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (and:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "rK")))]
- X ""
- X "*
- {
- X extern rtx operand_to_logical_operand ();
- X operands[2] = operand_to_logical_operand (operands[2]);
- X return \"AND %0,%1,%2\";
- }")
- X
- (define_insn ""
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
- X (not:SI (match_operand:SI 2 "general_operand" "rK"))))]
- X ""
- X "*
- {
- X extern rtx operand_to_logical_operand ();
- X operands[2] = operand_to_logical_operand (operands[2]);
- X return \"NAND %0,%1,%2\";
- }")
- X
- (define_insn "iorsi3"
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (ior:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "rK")))]
- X ""
- X "*
- {
- X extern rtx operand_to_logical_operand ();
- X operands[2] = operand_to_logical_operand (operands[2]);
- X return \"OR %0,%1,%2\";
- }")
- X
- (define_insn "xorsi3"
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (xor:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "rK")))]
- X ""
- X "*
- {
- X extern rtx operand_to_logical_operand ();
- X operands[2] = operand_to_logical_operand (operands[2]);
- X return \"XOR %0,%1,%2\";
- }")
- X
- (define_insn "negsi2"
- X [(set (match_operand:SI 0 "register_operand" "=r,r")
- X (neg:SI (match_operand:SI 1 "general_operand" "r,I")))]
- X ""
- X "@
- X CPL %0,%1
- X SUB %0,R0,%1 ; CPL %0,%1")
- X
- (define_insn "one_cmplsi2"
- X [(set (match_operand:SI 0 "register_operand" "=r,r")
- X (not:SI (match_operand:SI 1 "general_operand" "r,I")))]
- X ""
- X "@
- X NEG %0,%1
- X NADD %0,R0,%1 ; NEG %0,%1")
- X
- ;;
- ;; Shift- and rotate operations
- ;; ----------------------------
- ;;
- X
- ;; arithmetic shift left
- (define_insn "ashlsi3"
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (ashift:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "rI")))]
- X "TARGET_BARREL_SHIFTER"
- X "ASHL %0,%1,%2")
- X
- (define_insn ""
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (ashift:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "I")))]
- X "GET_CODE (operands[2]) == CONST_INT"
- X "*
- {
- X int shift_count = INTVAL (operands[2]);
- X output_asm_insn (\"ASHL %0,%1\", operands);
- X while (--shift_count)
- X output_asm_insn (\"ASHL %0,%0\", operands);
- }")
- X
- ;; arithmetic shift right
- (define_insn "ashrsi3"
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "rI")))]
- X "TARGET_BARREL_SHIFTER"
- X "ASHR %0,%1,%2")
- X
- (define_insn ""
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "I")))]
- X "GET_CODE (operands[2]) == CONST_INT"
- X "*
- {
- X int shift_count = INTVAL (operands[2]);
- X output_asm_insn (\"ASHR %0,%1\", operands);
- X while (--shift_count)
- X output_asm_insn (\"ASHR %0,%0\", operands);
- }")
- X
- ;; logical shift right
- (define_insn "lshrsi3"
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "rI")))]
- X "TARGET_BARREL_SHIFTER"
- X "LSHR %0,%1,%2")
- X
- (define_insn ""
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "I")))]
- X "GET_CODE (operands[2]) == CONST_INT"
- X "*
- {
- X int shift_count = INTVAL (operands[2]);
- X output_asm_insn (\"LSHR %0,%1\", operands);
- X while (--shift_count)
- X output_asm_insn (\"LSHR %0,%0\", operands);
- }")
- X
- ;; rotate left
- (define_insn "rotlsi3"
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (rotate:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "rI")))]
- X "TARGET_BARREL_SHIFTER"
- X "ROL %0,%1,%2")
- X
- (define_insn ""
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (rotate:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "I")))]
- X "GET_CODE (operands[2]) == CONST_INT"
- X "*
- {
- X int shift_count = INTVAL (operands[2]);
- X output_asm_insn (\"ROL %0,%1\", operands);
- X while (--shift_count)
- X output_asm_insn (\"ROL %0,%0\", operands);
- }")
- X
- ;; rotate right
- (define_insn "rotrsi3"
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (rotatert:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "rI")))]
- X "TARGET_BARREL_SHIFTER"
- X "ROR %0,%1,%2")
- X
- (define_insn ""
- X [(set (match_operand:SI 0 "register_operand" "=r")
- X (rotatert:SI (match_operand:SI 1 "register_operand" "r")
- X (match_operand:SI 2 "general_operand" "I")))]
- X "GET_CODE (operands[2]) == CONST_INT"
- X "*
- {
- X int shift_count = INTVAL (operands[2]);
- X output_asm_insn (\"ROR %0,%1\", operands);
- X while (--shift_count)
- X output_asm_insn (\"ROR %0,%0\", operands);
- }")
- X
- ;;
- ;; Misc operations
- ;; ---------------
- ;;
- X
- (define_insn "nop"
- X [(const_int 0)]
- X ""
- X "NOP")
- X
- X
- ;;- Local variables:
- ;;- mode:emacs-lisp
- ;;- comment-start: ";;- "
- ;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
- ;;- eval: (modify-syntax-entry ?[ "(]")
- ;;- eval: (modify-syntax-entry ?] ")[")
- ;;- eval: (modify-syntax-entry ?{ "(}")
- ;;- eval: (modify-syntax-entry ?} "){")
- ;;- End:
- SHAR_EOF
- chmod 0664 risc32.md ||
- echo 'restore of risc32.md failed'
- Wc_c="`wc -c < 'risc32.md'`"
- test 13802 -eq "$Wc_c" ||
- echo 'risc32.md: original size 13802, current size' "$Wc_c"
- fi
- # ============= xm-risc32.h ==============
- if test -f 'xm-risc32.h' -a X"$1" != X"-c"; then
- echo 'x - skipping xm-risc32.h (File already exists)'
- else
- echo 'x - extracting xm-risc32.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'xm-risc32.h' &&
- /* Configuration for GNU C-compiler for IMS RISC32 controller.
- X Copyright (C) 1992 Andreas Luik <luik@isa.de>.
- X
- This file is part of GNU CC.
- X
- 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.
- X
- 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.
- X
- 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
- X
- X
- /* #defines that need visibility everywhere. */
- #define FALSE 0
- #define TRUE 1
- X
- /* Arguments to use with `exit'. */
- #define SUCCESS_EXIT_CODE 0
- #define FATAL_EXIT_CODE 33
- X
- /* Doubles are stored in memory with the high order word first. This
- X matters when cross-compiling. */
- #define HOST_WORDS_BIG_ENDIAN
- X
- /* This describes the machine the compiler is hosted on. */
- #define HOST_BITS_PER_CHAR 16
- #define HOST_BITS_PER_SHORT 16
- #define HOST_BITS_PER_INT 32
- #define HOST_BITS_PER_LONG 32
- #define HOST_BITS_PER_LONGLONG 64
- X
- /* target machine dependencies.
- X tm.h is a symbolic link to the actual target specific file. */
- #include "tm.h"
- X
- /* If compiled with GNU C, use the built-in alloca. */
- #ifdef __GNUC__
- /* Use an arg in this macro because that's what some other
- X system does--let's avoid conflict. */
- #define alloca(x) __builtin_alloca(x)
- #endif
- SHAR_EOF
- chmod 0664 xm-risc32.h ||
- echo 'restore of xm-risc32.h failed'
- Wc_c="`wc -c < 'xm-risc32.h'`"
- test 1657 -eq "$Wc_c" ||
- echo 'xm-risc32.h: original size 1657, current size' "$Wc_c"
- fi
- exit 0
-
- --
- Andreas Luik E-Mail: luik@isa.de
- (postmaster@isa.de) UUCP: ...!{uunet!unido,pyramid}!isaak!luik
-
-
-