diff options
author | phk <phk@FreeBSD.org> | 1994-08-02 20:15:59 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1994-08-02 20:15:59 +0000 |
commit | 5ba9f35203b5fe0daba8f1ded6df2bcb38880681 (patch) | |
tree | 5a7e9c8d4cf5d1bd3b4c8577610d406f89f85545 /gnu/usr.bin/cc/include | |
parent | ceb5ca06c6ed8827fe5069db7033fc696325b681 (diff) | |
download | FreeBSD-src-5ba9f35203b5fe0daba8f1ded6df2bcb38880681.zip FreeBSD-src-5ba9f35203b5fe0daba8f1ded6df2bcb38880681.tar.gz |
Here comes the right import of gcc-2.6.0.
Diffstat (limited to 'gnu/usr.bin/cc/include')
57 files changed, 15252 insertions, 0 deletions
diff --git a/gnu/usr.bin/cc/include/basic-block.h b/gnu/usr.bin/cc/include/basic-block.h new file mode 100644 index 0000000..b1bc002 --- /dev/null +++ b/gnu/usr.bin/cc/include/basic-block.h @@ -0,0 +1,68 @@ +/* Define control and data flow tables, and regsets. + Copyright (C) 1987 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* Number of bits in each actual element of a regset. */ + +#define REGSET_ELT_BITS HOST_BITS_PER_WIDE_INT + +/* Type to use for a regset element. Note that lots of code assumes + that the initial part of a regset that contains information on the + hard registers is the same format as a HARD_REG_SET. */ + +#define REGSET_ELT_TYPE unsigned HOST_WIDE_INT + +/* Define the type for a pointer to a set with a bit for each + (hard or pseudo) register. */ + +typedef REGSET_ELT_TYPE *regset; + +/* Size of a regset for the current function, + in (1) bytes and (2) elements. */ + +extern int regset_bytes; +extern int regset_size; + +/* Number of basic blocks in the current function. */ + +extern int n_basic_blocks; + +/* Index by basic block number, get first insn in the block. */ + +extern rtx *basic_block_head; + +/* Index by basic block number, get last insn in the block. */ + +extern rtx *basic_block_end; + +/* Index by basic block number, get address of regset + describing the registers live at the start of that block. */ + +extern regset *basic_block_live_at_start; + +/* Indexed by n, gives number of basic block that (REG n) is used in. + If the value is REG_BLOCK_GLOBAL (-2), + it means (REG n) is used in more than one basic block. + REG_BLOCK_UNKNOWN (-1) means it hasn't been seen yet so we don't know. + This information remains valid for the rest of the compilation + of the current function; it is used to control register allocation. */ + +#define REG_BLOCK_UNKNOWN -1 +#define REG_BLOCK_GLOBAL -2 +extern int *reg_basic_block; diff --git a/gnu/usr.bin/cc/include/bc-arity.h b/gnu/usr.bin/cc/include/bc-arity.h new file mode 100644 index 0000000..d311745 --- /dev/null +++ b/gnu/usr.bin/cc/include/bc-arity.h @@ -0,0 +1,232 @@ +{ 0, 0, 0, {0}}, +{ 1, 0, 0, {0}}, +{ 1, 2, 0, {0}}, +{ 1, 2, 0, {0}}, +{ 0, 0, 1, {SIcode, }}, +{ 0, 0, 1, {SIcode, }}, +{ 0, 1, 1, {QIcode, }}, +{ 0, 1, 1, {HIcode, }}, +{ 0, 1, 1, {SIcode, }}, +{ 0, 1, 1, {DIcode, }}, +{ 0, 1, 1, {SFcode, }}, +{ 0, 1, 1, {DFcode, }}, +{ 0, 1, 1, {XFcode, }}, +{ 0, 1, 1, {Pcode, }}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 2, 0, 0, {0}}, +{ 2, 0, 0, {0}}, +{ 2, 0, 0, {0}}, +{ 2, 0, 0, {0}}, +{ 2, 0, 0, {0}}, +{ 2, 0, 0, {0}}, +{ 2, 0, 0, {0}}, +{ 2, 0, 0, {0}}, +{ 3, 0, 0, {0}}, +{ 2, 0, 0, {0}}, +{ 1, 1, 1, {SIcode, }}, +{ 1, 1, 0, {0}}, +{ 0, 1, 1, {SIcode, }}, +{ 0, 1, 1, {SIcode, }}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 3, 1, 0, {0}}, +{ 3, 1, 0, {0}}, +{ 4, 0, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 1, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 4, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 4, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 4, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 2, 1, 0, {0}}, +{ 4, 1, 0, {0}}, +{ 1, 0, 1, {SIcode, }}, +{ 1, 0, 1, {SIcode, }}, +{ 0, 0, 1, {SIcode, }}, +{ 0, 0, 0, {0}}, +{ 1, 0, 3, {SIcode, SIcode, SIcode, }}, +{ 1, 0, 3, {SIcode, SIcode, SIcode, }}, +{ 1, 0, 3, {SIcode, SIcode, SIcode, }}, +{ 1, 0, 3, {SIcode, SIcode, SIcode, }}, +{ 3, 0, 0, {0}}, +{ 0, 1, 0, {0}}, +{ 0, 0, 0, {0}}, +{ 0, 0, 1, {SIcode, }}, diff --git a/gnu/usr.bin/cc/include/bc-emit.h b/gnu/usr.bin/cc/include/bc-emit.h new file mode 100644 index 0000000..c00da5b --- /dev/null +++ b/gnu/usr.bin/cc/include/bc-emit.h @@ -0,0 +1,133 @@ +/* bc-emit.h - declare entry points for producing object files of bytecodes. */ + +/* Internal format of symbol table for the object file. */ +struct bc_sym +{ + /* Private copy separately malloc'd. */ + char *name; + + /* Symbol has a defined value. */ + unsigned int defined:1; + + /* Symbol has been globalized. */ + unsigned int global:1; + + /* Symbol is common. */ + unsigned int common:1; + + /* Value if defined. */ + unsigned long int val; + + /* Used in internal symbol table structure. */ + struct bc_sym *next; +}; + + +/* List of symbols defined in a particular segment. */ +struct bc_segsym +{ + struct bc_sym *sym; + struct bc_segsym *next; +}; + + +/* List of relocations needed in a particular segment. */ +struct bc_segreloc +{ + /* Offset of datum to be relocated. */ + unsigned int offset; + + /* Symbol to be relocated by. */ + struct bc_sym *sym; + + struct bc_segreloc *next; +}; + + +/* Segment of an object file. */ +struct bc_seg +{ + /* Size allocated to contents. */ + unsigned int alloc; + + /* Pointer to base of contents. */ + char *data; + + /* Actual size of contents. */ + unsigned int size; + + /* List of symbols defined in this segment. */ + struct bc_segsym *syms; + + /* List of relocations for this segment. */ + struct bc_segreloc *relocs; +}; + + +/* Anonymous bytecode label within a single function. */ +struct bc_label +{ + /* Offset of label from start of segment. */ + unsigned int offset; + + /* True when offset is valid. */ + unsigned int defined:1; + + /* Unique bytecode ID, used to determine innermost + block containment */ + int uid; + + /* Next node in list */ + struct bc_label *next; +}; + + +/* Reference to a bc_label; a list of all such references is kept for + the function, then when it is finished they are backpatched to + contain the correct values. */ + +struct bc_labelref +{ + /* Label referenced. */ + struct bc_label *label; + + /* Code offset of reference. */ + unsigned int offset; + + /* Next labelref in list */ + struct bc_labelref *next; +}; + + + +extern void bc_initialize(); +extern int bc_begin_function(); +extern char *bc_emit_trampoline(); +extern void bc_emit_bytecode(); +extern void bc_emit_bytecode_const(); +extern struct bc_label *bc_get_bytecode_label(); +extern int bc_emit_bytecode_labeldef(); +extern void bc_emit_bytecode_labelref(); +extern void bc_emit_code_labelref(); +extern char *bc_end_function(); +extern void bc_align_const(); +extern void bc_emit_const(); +extern void bc_emit_const_skip(); +extern int bc_emit_const_labeldef(); +extern void bc_emit_const_labelref(); +extern void bc_align_data(); +extern void bc_emit_data(); +extern void bc_emit_data_skip(); +extern int bc_emit_data_labeldef(); +extern void bc_emit_data_labelref(); +extern int bc_define_pointer (); +extern int bc_emit_common(); +extern void bc_globalize_label(); +extern void bc_text(); +extern void bc_data(); +extern void bc_align(); +extern void bc_emit(); +extern void bc_emit_skip(); +extern int bc_emit_labeldef(); +extern void bc_emit_labelref(); +extern void bc_write_file(); diff --git a/gnu/usr.bin/cc/include/bc-opcode.h b/gnu/usr.bin/cc/include/bc-opcode.h new file mode 100644 index 0000000..ba5cafe --- /dev/null +++ b/gnu/usr.bin/cc/include/bc-opcode.h @@ -0,0 +1,238 @@ +/* This file is automatically generated from bytecode.def, +do not make any changes here. Instead edit bytecode.def. */ + +enum bytecode_opcode +{ neverneverland, + drop, + duplicate, + over, + setstackSI, + adjstackSI, + constQI, + constHI, + constSI, + constDI, + constSF, + constDF, + constXF, + constP, + loadQI, + loadHI, + loadSI, + loadDI, + loadSF, + loadDF, + loadXF, + loadP, + storeQI, + storeHI, + storeSI, + storeDI, + storeSF, + storeDF, + storeXF, + storeP, + storeBLK, + clearBLK, + addconstPSI, + newlocalSI, + localP, + argP, + convertQIHI, + convertHISI, + convertSIDI, + convertQISI, + convertQUHU, + convertHUSU, + convertSUDU, + convertQUSU, + convertSFDF, + convertDFXF, + convertHIQI, + convertSIHI, + convertDISI, + convertSIQI, + convertSUQU, + convertDFSF, + convertXFDF, + convertSISF, + convertSIDF, + convertSIXF, + convertSUSF, + convertSUDF, + convertSUXF, + convertDISF, + convertDIDF, + convertDIXF, + convertDUSF, + convertDUDF, + convertDUXF, + convertSFSI, + convertDFSI, + convertXFSI, + convertSFSU, + convertDFSU, + convertXFSU, + convertSFDI, + convertDFDI, + convertXFDI, + convertSFDU, + convertDFDU, + convertXFDU, + convertPSI, + convertSIP, + convertSIT, + convertDIT, + convertSFT, + convertDFT, + convertXFT, + convertPT, + zxloadBI, + sxloadBI, + sstoreBI, + addSI, + addDI, + addSF, + addDF, + addXF, + addPSI, + subSI, + subDI, + subSF, + subDF, + subXF, + subPP, + mulSI, + mulDI, + mulSU, + mulDU, + mulSF, + mulDF, + mulXF, + divSI, + divDI, + divSU, + divDU, + divSF, + divDF, + divXF, + modSI, + modDI, + modSU, + modDU, + andSI, + andDI, + iorSI, + iorDI, + xorSI, + xorDI, + lshiftSI, + lshiftSU, + lshiftDI, + lshiftDU, + rshiftSI, + rshiftSU, + rshiftDI, + rshiftDU, + ltSI, + ltSU, + ltDI, + ltDU, + ltSF, + ltDF, + ltXF, + ltP, + leSI, + leSU, + leDI, + leDU, + leSF, + leDF, + leXF, + leP, + geSI, + geSU, + geDI, + geDU, + geSF, + geDF, + geXF, + geP, + gtSI, + gtSU, + gtDI, + gtDU, + gtSF, + gtDF, + gtXF, + gtP, + eqSI, + eqDI, + eqSF, + eqDF, + eqXF, + eqP, + neSI, + neDI, + neSF, + neDF, + neXF, + neP, + negSI, + negDI, + negSF, + negDF, + negXF, + notSI, + notDI, + notT, + predecQI, + predecHI, + predecSI, + predecDI, + predecP, + predecSF, + predecDF, + predecXF, + predecBI, + preincQI, + preincHI, + preincSI, + preincDI, + preincP, + preincSF, + preincDF, + preincXF, + preincBI, + postdecQI, + postdecHI, + postdecSI, + postdecDI, + postdecP, + postdecSF, + postdecDF, + postdecXF, + postdecBI, + postincQI, + postincHI, + postincSI, + postincDI, + postincP, + postincSF, + postincDF, + postincXF, + postincBI, + xjumpif, + xjumpifnot, + jump, + jumpP, + caseSI, + caseSU, + caseDI, + caseDU, + call, + returnP, + ret, + linenote, + LAST_AND_UNUSED_OPCODE +}; diff --git a/gnu/usr.bin/cc/include/bc-optab.h b/gnu/usr.bin/cc/include/bc-optab.h new file mode 100644 index 0000000..f42485f --- /dev/null +++ b/gnu/usr.bin/cc/include/bc-optab.h @@ -0,0 +1,74 @@ +/* Bytecode token definitions for GNU C-compiler. + Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +extern void bc_expand_conversion (); +extern void bc_expand_truth_conversion (); +extern void bc_expand_binary_operation (); +extern void bc_expand_unary_operation (); + +struct binary_operator +{ + enum bytecode_opcode opcode; + enum typecode result; + enum typecode arg0; + enum typecode arg1; +}; + +extern struct binary_operator optab_plus_expr[]; +extern struct binary_operator optab_minus_expr[]; +extern struct binary_operator optab_mult_expr[]; +extern struct binary_operator optab_trunc_div_expr[]; +extern struct binary_operator optab_trunc_mod_expr[]; +extern struct binary_operator optab_rdiv_expr[]; +extern struct binary_operator optab_bit_and_expr[]; +extern struct binary_operator optab_bit_ior_expr[]; +extern struct binary_operator optab_bit_xor_expr[]; +extern struct binary_operator optab_lshift_expr[]; +extern struct binary_operator optab_rshift_expr[]; +extern struct binary_operator optab_truth_and_expr[]; +extern struct binary_operator optab_truth_or_expr[]; +extern struct binary_operator optab_lt_expr[]; +extern struct binary_operator optab_le_expr[]; +extern struct binary_operator optab_ge_expr[]; +extern struct binary_operator optab_gt_expr[]; +extern struct binary_operator optab_eq_expr[]; +extern struct binary_operator optab_ne_expr[]; + +struct unary_operator +{ + enum bytecode_opcode opcode; + enum typecode result; + enum typecode arg0; +}; + +extern struct unary_operator optab_negate_expr[]; +extern struct unary_operator optab_bit_not_expr[]; +extern struct unary_operator optab_truth_not_expr[]; + +struct increment_operator +{ + enum bytecode_opcode opcode; + enum typecode arg; +}; + +extern struct increment_operator optab_predecrement_expr[]; +extern struct increment_operator optab_preincrement_expr[]; +extern struct increment_operator optab_postdecrement_expr[]; +extern struct increment_operator optab_postincrement_expr[]; diff --git a/gnu/usr.bin/cc/include/bc-typecd.def b/gnu/usr.bin/cc/include/bc-typecd.def new file mode 100644 index 0000000..fd92cdd --- /dev/null +++ b/gnu/usr.bin/cc/include/bc-typecd.def @@ -0,0 +1,21 @@ +/* Typecodes used by the interpreter and their related + machine modes and types. + + The last argument is used for retrieving the given + type from a varargs list. Due to a bug in varargs, + the type has to be the generic machine type of + larger. */ + +DEFTYPECODE (QIcode, "QI", QImode, SItype) +DEFTYPECODE (QUcode, "QU", QImode, SUtype) +DEFTYPECODE (HIcode, "HI", HImode, SItype) +DEFTYPECODE (HUcode, "HU", HImode, SUtype) +DEFTYPECODE (SIcode, "SI", SImode, SItype) +DEFTYPECODE (SUcode, "SU", SImode, SUtype) +DEFTYPECODE (DIcode, "DI", DImode, DItype) +DEFTYPECODE (DUcode, "DU", DImode, DUtype) +DEFTYPECODE (SFcode, "SF", SFmode, SFtype) +DEFTYPECODE (DFcode, "DF", DFmode, DFtype) +DEFTYPECODE (XFcode, "XF", XFmode, XFtype) +DEFTYPECODE (Pcode, "P", PSImode, Ptype) +DEFTYPECODE (Tcode, "T", SImode, SItype) diff --git a/gnu/usr.bin/cc/include/bc-typecd.h b/gnu/usr.bin/cc/include/bc-typecd.h new file mode 100644 index 0000000..097cd62 --- /dev/null +++ b/gnu/usr.bin/cc/include/bc-typecd.h @@ -0,0 +1,53 @@ +/* Typecode definitions for Bytecode Interpreter. + Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef TYPECODE_H +#define TYPECODE_H + +enum typecode +{ +#define DEFTYPECODE(CODE, NAME, MACHMODE, TYPE) CODE, +#include "bc-typecd.def" +#undef DEFTYPECODE + + LAST_AND_UNUSED_TYPECODE +}; + +/* Determine if a given type is integer. */ +#define TYPECODE_INTEGER_P(TYPECODE) ((int) (TYPECODE) < (int) SFcode) + +/* Determine if a given type is unsigned. */ +#define TYPECODE_UNSIGNED_P(TYPECODE) \ + (TYPECODE_INTEGER_P(TYPECODE) && (int) (TYPECODE) & 1) + +/* Determine if a given type is signed. */ +#define TYPECODE_SIGNED_P(TYPECODE) \ + (TYPECODE_INTEGER_P(TYPECODE) && !((int) (TYPECODE) & 1)) + +/* Determine if a given type is floating. */ +#define TYPECODE_FLOAT_P(TYPECODE) \ + ((int) (TYPECODE) < (int) Pcode && !TYPECODE_INTEGER_P(TYPECODE)) + +/* Determine if the given type is arithmetic. */ +#define TYPECODE_ARITH_P(TYPECODE) \ + (TYPECODE_INTEGER_P(TYPECODE) || TYPECODE_FLOAT_P(TYPECODE)) + +#define NUM_TYPECODES ((int) LAST_AND_UNUSED_TYPECODE) + +#endif diff --git a/gnu/usr.bin/cc/include/bi-run.h b/gnu/usr.bin/cc/include/bi-run.h new file mode 100644 index 0000000..669f2ab --- /dev/null +++ b/gnu/usr.bin/cc/include/bi-run.h @@ -0,0 +1,165 @@ +/* Definitions for Bytecode Interpreter. + Copyright (C) 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#define MAXLITERALS 5 + +struct arityvec +{ + char ninputs; + char noutputs; + char nliterals; + char literals[MAXLITERALS]; +}; + +struct argtype +{ + int modealign; /* Argument mode:alignment */ + int size; /* Argument size, in bytes */ +}; + +struct callinfo +{ + int nargs; /* Number of arguments in call */ + struct argtype retvaltype; /* Type of return value */ + struct argtype argtypes[1]; /* Argument types */ +}; + +/* Structure describing a bytecode function. If this changes, we also + need to change expand_function_end () in bc-trans.c */ +struct bytecode +{ + int stacksize; /* Depth required of evaluation stack. */ + int localsize; /* Size in bytes of local variables. */ + unsigned char *pc0; /* Initial program counter. */ + void **ptrlit; /* Vector of (relocatable) pointer literals. */ + struct callinfo *callinfo; /* Vector of procedure call type info. */ +}; + + +#define INTERP_BPC 8 /* Bits per char */ +#define INTERP_BPI \ + (sizeof (int) * INTERP_BPC) /* Bits per int */ + + +#ifndef min +#define min(L, R) ((L) < (R) ? (L) : (R)) +#endif + + +/* bit field operations. */ + +/* Low (high) mask: int with low (high) N bits set */ + +#define LM(N) ((1 << (N)) - 1) +#define HM(N) ((~LM (INTERP_BPI - (N)))) + + +/* Sign-extend SIZE low bits of VALUE to integer (typeof VALUE) + Signed bitfields are loaded from memory by the sxloadBI instruction, + which first retrieves the bitfield with XFIELD and then sign extends + it to an SItype. */ + +#define EXTEND(SIZE, VALUE) \ + ({ SUtype value = (SUtype) (VALUE); \ + (value & (1 << ((SIZE) - 1)) ? value | ~LM (SIZE) : value); }) + + +/* Given OFFSET:SIZE for a bitfield, calculate: + + [1] BYTE_OFFSET = the byte offset of the bit field. + [2] BIT_OFFSET = the bit offset of the bit field (less than INTERP_BPC). + [3] NBYTES = the number of integral bytes in the bit field. + [4] TRAILING_BITS= the number of trailing bits (less than INTERP_BPC). + + + , , , , , (memory bytes) + ---------------- (bitfield) + | | || | | (divisions) + ^ ^ ^ ^ + | | | |__ [4] (bits) + | | |_________ [3] (bytes) + | |_________________ [2] (bits) + |___________________________ [1] (bytes) + + + The above applies to BYTE_LOW_ENDIAN machines. In BYTE_BIG_ENDIAN machines, the + bit numbering is reversed (i.e. bit 0 is the sign bit). + + (Alright, so I drew this to keep my tongue in cheek while writing the code below, + not because I'm into ASCII art.) */ + + +#define BI_PARAMS(OFFSET, SIZE, BYTE_OFFSET, BIT_OFFSET, NBYTES, TRAILING_BITS) \ + { BYTE_OFFSET = (OFFSET) / (INTERP_BPC); \ + BIT_OFFSET = (OFFSET) % (INTERP_BPC); \ + NBYTES = ((SIZE) - (INTERP_BPC - (BIT_OFFSET))) / INTERP_BPC; \ + if ((NBYTES) < 0 || ((NBYTES) > 64)) \ + NBYTES = 0; \ + if ((SIZE) + (BIT_OFFSET) <= INTERP_BPC) \ + TRAILING_BITS = 0; \ + else \ + TRAILING_BITS = ((SIZE) - (INTERP_BPC - (BIT_OFFSET))) % INTERP_BPC; } + + +/* SHIFT_IN_BITS retrieves NBITS bits from SOURCE and shifts into + DEST. The bit field starts OFFSET bits into SOURCE. + + OR_IN_BITS copies the NBITS low bits from VALUE into a the bitfield in + DEST offset by OFFSET bits. */ + + +#if BYTES_BIG_ENDIAN + +#define SHIFT_IN_BITS(DEST, SOURCE, OFFSET, NBITS) \ + (DEST = ((DEST) << (NBITS)) \ + | (LM ((NBITS)) \ + & ((SOURCE) >> (INTERP_BPC - (OFFSET) - (NBITS))))) + +#define OR_IN_BITS(DEST, VALUE, OFFSET, NBITS) \ + (DEST = ((DEST) & ~(LM ((NBITS)) << (INTERP_BPC - (OFFSET) - (NBITS)))) \ + | (((VALUE) & LM ((NBITS))) << (INTERP_BPC - (OFFSET) - (NBITS)))) + +#else + +#define SHIFT_IN_BITS(DEST, SOURCE, OFFSET, NBITS) \ + (DEST = ((DEST) << (NBITS)) \ + | (LM ((NBITS)) \ + & ((SOURCE) >> (OFFSET)))) + +#define OR_IN_BITS(DEST, VALUE, OFFSET, NBITS) \ + (DEST = ((DEST) & ~(LM ((NBITS)) << (OFFSET))) \ + | (((VALUE) & LM ((NBITS))) << (OFFSET))) + +#endif + + +/* Procedure call; arguments are a pointer to the function to be called, + a pointer to a place to store the return value, a pointer to a vector + describing the type of procedure call, and the interpreter's stack pointer, + which will point to the first of the arguments at this point. */ + +#define CALL(FUNC, CALLDESC, RETVAL, SP) __call(FUNC, CALLDESC, RETVAL, SP) + + +/* Procedure return; arguments are a pointer to the calldesc for this + function, and a pointer to the place where the value to be returned + may be found. Generally the MACHARGS above contain a machine dependent + cookie that is used to determine where to jump to. */ + +#define PROCRET(CALLDESC, RETVAL) return diff --git a/gnu/usr.bin/cc/include/bytecode.h b/gnu/usr.bin/cc/include/bytecode.h new file mode 100644 index 0000000..87030be --- /dev/null +++ b/gnu/usr.bin/cc/include/bytecode.h @@ -0,0 +1,91 @@ +/* Bytecode definitions for GNU C-compiler. + Copyright (C) 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +extern int output_bytecode; +extern int stack_depth; +extern int max_stack_depth; + +/* Emit DI constant according to target machine word ordering */ + +#if WORDS_BIG_ENDIAN + +#define bc_emit_bytecode_DI_const(CST) \ +{ int opcode; \ + opcode = TREE_INT_CST_HIGH (CST); \ + bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \ + opcode = TREE_INT_CST_LOW (CST); \ + bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \ +} + +#else + +#define bc_emit_bytecode_DI_const(CST) \ +{ int opcode; \ + opcode = TREE_INT_CST_LOW (CST); \ + bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \ + opcode = TREE_INT_CST_HIGH (CST); \ + bc_emit_bytecode_const ((char *) &opcode, sizeof opcode); \ +} + +#endif + + +extern void bc_expand_expr (); +extern void bc_output_data_constructor (); +extern void bc_store_field (); +extern void bc_load_bit_field (); +extern void bc_store_bit_field (); +extern void bc_push_offset_and_size (); +extern void bc_init_mode_to_code_map (); + +/* These are just stubs, so the compiler will compile for targets + that aren't yet supported by the bytecode generator. */ + +#ifndef TARGET_SUPPORTS_BYTECODE + +#define MACHINE_SEG_ALIGN 1 +#define INT_ALIGN 1 +#define PTR_ALIGN 1 +#define NAMES_HAVE_UNDERSCORES +#define BC_NOP (0) +#define BC_GLOBALIZE_LABEL(FP, NAME) BC_NOP +#define BC_OUTPUT_COMMON(FP, NAME, SIZE, ROUNDED) BC_NOP +#define BC_OUTPUT_LOCAL(FP, NAME, SIZE, ROUNDED) BC_NOP +#define BC_OUTPUT_ALIGN(FP, ALIGN) BC_NOP +#define BC_OUTPUT_LABEL(FP, NAME) BC_NOP +#define BC_OUTPUT_SKIP(FP, SIZE) BC_NOP +#define BC_OUTPUT_LABELREF(FP, NAME) BC_NOP +#define BC_OUTPUT_FLOAT(FP, VAL) BC_NOP +#define BC_OUTPUT_DOUBLE(FP, VAL) BC_NOP +#define BC_OUTPUT_BYTE(FP, VAL) BC_NOP +#define BC_OUTPUT_FILE ASM_OUTPUT_FILE +#define BC_OUTPUT_ASCII ASM_OUTPUT_ASCII +#define BC_OUTPUT_IDENT ASM_OUTPUT_IDENT +#define BCXSTR(RTX) ((RTX)->bc_label) +#define BC_WRITE_FILE(FP) BC_NOP +#define BC_WRITE_SEGSYM(SEGSYM, FP) BC_NOP +#define BC_WRITE_RELOC_ENTRY(SEGRELOC, FP, OFFSET) BC_NOP +#define BC_START_BYTECODE_LINE(FP) BC_NOP +#define BC_WRITE_BYTECODE(SEP, VAL, FP) BC_NOP +#define BC_WRITE_RTL(R, FP) BC_NOP +#define BC_EMIT_TRAMPOLINE(TRAMPSEG, CALLINFO) BC_NOP +#define VALIDATE_STACK BC_NOP + +#endif /* !TARGET_SUPPORTS_BYTECODE */ diff --git a/gnu/usr.bin/cc/include/bytetypes.h b/gnu/usr.bin/cc/include/bytetypes.h new file mode 100644 index 0000000..f915669 --- /dev/null +++ b/gnu/usr.bin/cc/include/bytetypes.h @@ -0,0 +1,35 @@ +/* These should come from genemit */ + +/* Use __signed__ in case compiling with -traditional. */ + +typedef __signed__ char QItype; +typedef unsigned char QUtype; +typedef __signed__ short int HItype; +typedef unsigned short int HUtype; +typedef __signed__ long int SItype; +typedef unsigned long int SUtype; +typedef __signed__ long long int DItype; +typedef unsigned long long int DUtype; +typedef float SFtype; +typedef double DFtype; +typedef long double XFtype; +typedef char *Ptype; +typedef int Ttype; + + +typedef union stacktype +{ + QItype QIval; + QUtype QUval; + HItype HIval; + HUtype HUval; + SItype SIval; + SUtype SUval; + DItype DIval; + DUtype DUval; + SFtype SFval; + DFtype DFval; + XFtype XFval; + Ptype Pval; + Ttype Tval; +} stacktype; diff --git a/gnu/usr.bin/cc/include/c-gperf.h b/gnu/usr.bin/cc/include/c-gperf.h new file mode 100644 index 0000000..edaaf22 --- /dev/null +++ b/gnu/usr.bin/cc/include/c-gperf.h @@ -0,0 +1,184 @@ +/* C code produced by gperf version 2.5 (GNU C++ version) */ +/* Command-line: gperf -p -j1 -i 1 -g -o -t -G -N is_reserved_word -k1,3,$ c-parse.gperf */ +struct resword { char *name; short token; enum rid rid; }; + +#define TOTAL_KEYWORDS 79 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 20 +#define MIN_HASH_VALUE 10 +#define MAX_HASH_VALUE 144 +/* maximum key range = 135, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#endif +static unsigned int +hash (str, len) + register char *str; + register int unsigned len; +{ + static unsigned char asso_values[] = + { + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 25, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, + 145, 145, 145, 145, 145, 1, 145, 46, 8, 15, + 61, 6, 36, 48, 3, 5, 145, 18, 63, 25, + 29, 76, 1, 145, 13, 2, 1, 51, 37, 9, + 9, 1, 3, 145, 145, 145, 145, 145, + }; + register int hval = len; + + switch (hval) + { + default: + case 3: + hval += asso_values[str[2]]; + case 2: + case 1: + hval += asso_values[str[0]]; + } + return hval + asso_values[str[len - 1]]; +} + +static struct resword wordlist[] = +{ + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"",}, + {"int", TYPESPEC, RID_INT}, + {"",}, {"",}, + {"__typeof__", TYPEOF, NORID}, + {"__signed__", TYPESPEC, RID_SIGNED}, + {"__imag__", IMAGPART, NORID}, + {"switch", SWITCH, NORID}, + {"__inline__", SCSPEC, RID_INLINE}, + {"else", ELSE, NORID}, + {"__iterator__", SCSPEC, RID_ITERATOR}, + {"__inline", SCSPEC, RID_INLINE}, + {"__extension__", EXTENSION, NORID}, + {"struct", STRUCT, NORID}, + {"__real__", REALPART, NORID}, + {"__const", TYPE_QUAL, RID_CONST}, + {"while", WHILE, NORID}, + {"__const__", TYPE_QUAL, RID_CONST}, + {"case", CASE, NORID}, + {"__complex__", TYPESPEC, RID_COMPLEX}, + {"__iterator", SCSPEC, RID_ITERATOR}, + {"bycopy", TYPE_QUAL, RID_BYCOPY}, + {"",}, {"",}, {"",}, + {"__complex", TYPESPEC, RID_COMPLEX}, + {"",}, + {"in", TYPE_QUAL, RID_IN}, + {"break", BREAK, NORID}, + {"@defs", DEFS, NORID}, + {"",}, {"",}, {"",}, + {"extern", SCSPEC, RID_EXTERN}, + {"if", IF, NORID}, + {"typeof", TYPEOF, NORID}, + {"typedef", SCSPEC, RID_TYPEDEF}, + {"__typeof", TYPEOF, NORID}, + {"sizeof", SIZEOF, NORID}, + {"",}, + {"return", RETURN, NORID}, + {"const", TYPE_QUAL, RID_CONST}, + {"__volatile__", TYPE_QUAL, RID_VOLATILE}, + {"@private", PRIVATE, NORID}, + {"@selector", SELECTOR, NORID}, + {"__volatile", TYPE_QUAL, RID_VOLATILE}, + {"__asm__", ASM_KEYWORD, NORID}, + {"",}, {"",}, + {"continue", CONTINUE, NORID}, + {"__alignof__", ALIGNOF, NORID}, + {"__imag", IMAGPART, NORID}, + {"__attribute__", ATTRIBUTE, NORID}, + {"",}, {"",}, + {"__attribute", ATTRIBUTE, NORID}, + {"for", FOR, NORID}, + {"",}, + {"@encode", ENCODE, NORID}, + {"id", OBJECTNAME, RID_ID}, + {"static", SCSPEC, RID_STATIC}, + {"@interface", INTERFACE, NORID}, + {"",}, + {"__signed", TYPESPEC, RID_SIGNED}, + {"",}, + {"__label__", LABEL, NORID}, + {"",}, {"",}, + {"__asm", ASM_KEYWORD, NORID}, + {"char", TYPESPEC, RID_CHAR}, + {"",}, + {"inline", SCSPEC, RID_INLINE}, + {"out", TYPE_QUAL, RID_OUT}, + {"register", SCSPEC, RID_REGISTER}, + {"__real", REALPART, NORID}, + {"short", TYPESPEC, RID_SHORT}, + {"",}, + {"enum", ENUM, NORID}, + {"inout", TYPE_QUAL, RID_INOUT}, + {"",}, + {"oneway", TYPE_QUAL, RID_ONEWAY}, + {"union", UNION, NORID}, + {"",}, + {"__alignof", ALIGNOF, NORID}, + {"",}, + {"@implementation", IMPLEMENTATION, NORID}, + {"",}, + {"@class", CLASS, NORID}, + {"",}, + {"@public", PUBLIC, NORID}, + {"asm", ASM_KEYWORD, NORID}, + {"",}, {"",}, {"",}, {"",}, {"",}, + {"default", DEFAULT, NORID}, + {"",}, + {"void", TYPESPEC, RID_VOID}, + {"",}, + {"@protected", PROTECTED, NORID}, + {"@protocol", PROTOCOL, NORID}, + {"",}, {"",}, {"",}, + {"volatile", TYPE_QUAL, RID_VOLATILE}, + {"",}, {"",}, + {"signed", TYPESPEC, RID_SIGNED}, + {"float", TYPESPEC, RID_FLOAT}, + {"@end", END, NORID}, + {"",}, {"",}, + {"unsigned", TYPESPEC, RID_UNSIGNED}, + {"@compatibility_alias", ALIAS, NORID}, + {"double", TYPESPEC, RID_DOUBLE}, + {"",}, {"",}, + {"auto", SCSPEC, RID_AUTO}, + {"",}, + {"goto", GOTO, NORID}, + {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, + {"do", DO, NORID}, + {"",}, {"",}, {"",}, {"",}, + {"long", TYPESPEC, RID_LONG}, +}; + +#ifdef __GNUC__ +__inline +#endif +struct resword * +is_reserved_word (str, len) + register char *str; + register unsigned int len; +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register char *s = wordlist[key].name; + + if (*s == *str && !strcmp (str + 1, s + 1)) + return &wordlist[key]; + } + } + return 0; +} diff --git a/gnu/usr.bin/cc/include/c-lex.h b/gnu/usr.bin/cc/include/c-lex.h new file mode 100644 index 0000000..ae67d4c --- /dev/null +++ b/gnu/usr.bin/cc/include/c-lex.h @@ -0,0 +1,79 @@ +/* Define constants for communication with c-parse.y. + Copyright (C) 1987, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + +enum rid +{ + RID_UNUSED, + RID_INT, + RID_CHAR, + RID_FLOAT, + RID_DOUBLE, + RID_VOID, + RID_UNUSED1, + + RID_UNSIGNED, + RID_SHORT, + RID_LONG, + RID_AUTO, + RID_STATIC, + RID_EXTERN, + RID_REGISTER, + RID_TYPEDEF, + RID_SIGNED, + RID_CONST, + RID_VOLATILE, + RID_INLINE, + RID_NOALIAS, + RID_ITERATOR, + RID_COMPLEX, + + RID_IN, + RID_OUT, + RID_INOUT, + RID_BYCOPY, + RID_ONEWAY, + RID_ID, + + RID_MAX +}; + +#define NORID RID_UNUSED + +#define RID_FIRST_MODIFIER RID_UNSIGNED + +/* The elements of `ridpointers' are identifier nodes + for the reserved type names and storage classes. + It is indexed by a RID_... value. */ +extern tree ridpointers[(int) RID_MAX]; + +/* the declaration found for the last IDENTIFIER token read in. + yylex must look this up to detect typedefs, which get token type TYPENAME, + so it is left around in case the identifier is not a typedef but is + used in a context which makes it a reference to a variable. */ +extern tree lastiddecl; + +extern char *token_buffer; /* Pointer to token buffer. */ + +extern tree make_pointer_declarator (); +extern void reinit_parse_for_function (); +extern int yylex (); + +extern char *get_directive_line (); diff --git a/gnu/usr.bin/cc/include/c-parse.h b/gnu/usr.bin/cc/include/c-parse.h new file mode 100644 index 0000000..dab903e --- /dev/null +++ b/gnu/usr.bin/cc/include/c-parse.h @@ -0,0 +1,65 @@ +typedef union {long itype; tree ttype; enum tree_code code; + char *filename; int lineno; } YYSTYPE; +#define IDENTIFIER 258 +#define TYPENAME 259 +#define SCSPEC 260 +#define TYPESPEC 261 +#define TYPE_QUAL 262 +#define CONSTANT 263 +#define STRING 264 +#define ELLIPSIS 265 +#define SIZEOF 266 +#define ENUM 267 +#define STRUCT 268 +#define UNION 269 +#define IF 270 +#define ELSE 271 +#define WHILE 272 +#define DO 273 +#define FOR 274 +#define SWITCH 275 +#define CASE 276 +#define DEFAULT 277 +#define BREAK 278 +#define CONTINUE 279 +#define RETURN 280 +#define GOTO 281 +#define ASM_KEYWORD 282 +#define TYPEOF 283 +#define ALIGNOF 284 +#define ALIGN 285 +#define ATTRIBUTE 286 +#define EXTENSION 287 +#define LABEL 288 +#define REALPART 289 +#define IMAGPART 290 +#define ASSIGN 291 +#define OROR 292 +#define ANDAND 293 +#define EQCOMPARE 294 +#define ARITHCOMPARE 295 +#define LSHIFT 296 +#define RSHIFT 297 +#define UNARY 298 +#define PLUSPLUS 299 +#define MINUSMINUS 300 +#define HYPERUNARY 301 +#define POINTSAT 302 +#define INTERFACE 303 +#define IMPLEMENTATION 304 +#define END 305 +#define SELECTOR 306 +#define DEFS 307 +#define ENCODE 308 +#define CLASSNAME 309 +#define PUBLIC 310 +#define PRIVATE 311 +#define PROTECTED 312 +#define PROTOCOL 313 +#define OBJECTNAME 314 +#define CLASS 315 +#define ALIAS 316 +#define OBJC_STRING 317 + + +extern YYSTYPE yylval; diff --git a/gnu/usr.bin/cc/include/c-tree.h b/gnu/usr.bin/cc/include/c-tree.h new file mode 100644 index 0000000..2300351 --- /dev/null +++ b/gnu/usr.bin/cc/include/c-tree.h @@ -0,0 +1,483 @@ +/* Definitions for C parsing and type checking. + Copyright (C) 1987, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _C_TREE_H +#define _C_TREE_H + +/* Language-dependent contents of an identifier. */ + +/* The limbo_value is used for block level extern declarations, which need + to be type checked against subsequent extern declarations. They can't + be referenced after they fall out of scope, so they can't be global. */ + +struct lang_identifier +{ + struct tree_identifier ignore; + tree global_value, local_value, label_value, implicit_decl; + tree error_locus, limbo_value; +}; + +/* Macros for access to language-specific slots in an identifier. */ +/* Each of these slots contains a DECL node or null. */ + +/* This represents the value which the identifier has in the + file-scope namespace. */ +#define IDENTIFIER_GLOBAL_VALUE(NODE) \ + (((struct lang_identifier *)(NODE))->global_value) +/* This represents the value which the identifier has in the current + scope. */ +#define IDENTIFIER_LOCAL_VALUE(NODE) \ + (((struct lang_identifier *)(NODE))->local_value) +/* This represents the value which the identifier has as a label in + the current label scope. */ +#define IDENTIFIER_LABEL_VALUE(NODE) \ + (((struct lang_identifier *)(NODE))->label_value) +/* This records the extern decl of this identifier, if it has had one + at any point in this compilation. */ +#define IDENTIFIER_LIMBO_VALUE(NODE) \ + (((struct lang_identifier *)(NODE))->limbo_value) +/* This records the implicit function decl of this identifier, if it + has had one at any point in this compilation. */ +#define IDENTIFIER_IMPLICIT_DECL(NODE) \ + (((struct lang_identifier *)(NODE))->implicit_decl) +/* This is the last function in which we printed an "undefined variable" + message for this identifier. Value is a FUNCTION_DECL or null. */ +#define IDENTIFIER_ERROR_LOCUS(NODE) \ + (((struct lang_identifier *)(NODE))->error_locus) + +/* In identifiers, C uses the following fields in a special way: + TREE_PUBLIC to record that there was a previous local extern decl. + TREE_USED to record that such a decl was used. + TREE_ADDRESSABLE to record that the address of such a decl was used. */ + +/* Nonzero means reject anything that ANSI standard C forbids. */ +extern int pedantic; + +/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */ +#define C_TYPE_FIELDS_READONLY(type) TREE_LANG_FLAG_1 (type) + +/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is volatile. */ +#define C_TYPE_FIELDS_VOLATILE(type) TREE_LANG_FLAG_2 (type) + +/* In a RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE + nonzero if the definition of the type has already started. */ +#define C_TYPE_BEING_DEFINED(type) TYPE_LANG_FLAG_0 (type) + +/* In a RECORD_TYPE, a sorted array of the fields of the type. */ +struct lang_type +{ + int len; + tree elts[1]; +}; + +/* Mark which labels are explicitly declared. + These may be shadowed, and may be referenced from nested functions. */ +#define C_DECLARED_LABEL_FLAG(label) TREE_LANG_FLAG_1 (label) + +/* Record whether a type or decl was written with nonconstant size. + Note that TYPE_SIZE may have simplified to a constant. */ +#define C_TYPE_VARIABLE_SIZE(type) TYPE_LANG_FLAG_1 (type) +#define C_DECL_VARIABLE_SIZE(type) DECL_LANG_FLAG_0 (type) + +/* Record in each node resulting from a binary operator + what operator was specified for it. */ +#define C_EXP_ORIGINAL_CODE(exp) ((enum tree_code) TREE_COMPLEXITY (exp)) + +#if 0 /* Not used. */ +/* Record whether a decl for a function or function pointer has + already been mentioned (in a warning) because it was called + but didn't have a prototype. */ +#define C_MISSING_PROTOTYPE_WARNED(decl) DECL_LANG_FLAG_2(decl) +#endif + +/* Store a value in that field. */ +#define C_SET_EXP_ORIGINAL_CODE(exp, code) \ + (TREE_COMPLEXITY (exp) = (int)(code)) + +/* Record whether a typedef for type `int' was actually `signed int'. */ +#define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp)) + +/* Nonzero for a declaration of a built in function if there has been no + occasion that would declare the function in ordinary C. + Using the function draws a pedantic warning in this case. */ +#define C_DECL_ANTICIPATED(exp) DECL_LANG_FLAG_3 ((exp)) + +/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as + TYPE_ARG_TYPES for functions with prototypes, but created for functions + without prototypes. */ +#define TYPE_ACTUAL_ARG_TYPES(NODE) TYPE_NONCOPIED_PARTS (NODE) + +/* Nonzero if the type T promotes to itself. + ANSI C states explicitly the list of types that promote; + in particular, short promotes to int even if they have the same width. */ +#define C_PROMOTING_INTEGER_TYPE_P(t) \ + (TREE_CODE ((t)) == INTEGER_TYPE \ + && (TYPE_MAIN_VARIANT (t) == char_type_node \ + || TYPE_MAIN_VARIANT (t) == signed_char_type_node \ + || TYPE_MAIN_VARIANT (t) == unsigned_char_type_node \ + || TYPE_MAIN_VARIANT (t) == short_integer_type_node \ + || TYPE_MAIN_VARIANT (t) == short_unsigned_type_node)) + +/* In a VAR_DECL, means the variable is really an iterator. */ +#define ITERATOR_P(D) (DECL_LANG_FLAG_4(D)) + +/* In a VAR_DECL for an iterator, means we are within + an explicit loop over that iterator. */ +#define ITERATOR_BOUND_P(NODE) ((NODE)->common.readonly_flag) + +/* in c-lang.c and objc-act.c */ +extern tree lookup_interface PROTO((tree)); +extern tree is_class_name PROTO((tree)); +extern void maybe_objc_check_decl PROTO((tree)); +extern int maybe_objc_comptypes PROTO((tree, tree, int)); +extern tree maybe_building_objc_message_expr PROTO((void)); +extern tree maybe_objc_method_name PROTO((tree)); +extern int recognize_objc_keyword PROTO((void)); +extern tree build_objc_string PROTO((int, char *)); + +/* in c-aux-info.c */ +extern void gen_aux_info_record PROTO((tree, int, int, int)); + +/* in c-common.c */ +extern void declare_function_name PROTO((void)); +extern void decl_attributes PROTO((tree, tree)); +extern void init_function_format_info PROTO((void)); +extern void record_function_format PROTO((tree, tree, int, int, int)); +extern void check_function_format PROTO((tree, tree, tree)); +/* Print an error message for invalid operands to arith operation CODE. + NOP_EXPR is used as a special case (see truthvalue_conversion). */ +extern void binary_op_error PROTO((enum tree_code)); +extern void c_expand_expr_stmt PROTO((tree)); +/* Validate the expression after `case' and apply default promotions. */ +extern tree check_case_value PROTO((tree)); +/* Concatenate a list of STRING_CST nodes into one STRING_CST. */ +extern tree combine_strings PROTO((tree)); +extern void constant_expression_warning PROTO((tree)); +extern tree convert_and_check PROTO((tree, tree)); +extern void overflow_warning PROTO((tree)); +extern void unsigned_conversion_warning PROTO((tree, tree)); +/* Read the rest of the current #-directive line. */ +extern char *get_directive_line STDIO_PROTO((FILE *)); +/* Subroutine of build_binary_op, used for comparison operations. + See if the operands have both been converted from subword integer types + and, if so, perhaps change them both back to their original type. */ +extern tree shorten_compare PROTO((tree *, tree *, tree *, enum tree_code *)); +/* Prepare expr to be an argument of a TRUTH_NOT_EXPR, + or validate its data type for an `if' or `while' statement or ?..: exp. */ +extern tree truthvalue_conversion PROTO((tree)); +extern tree type_for_mode PROTO((enum machine_mode, int)); +extern tree type_for_size PROTO((unsigned, int)); + +/* in c-convert.c */ +extern tree convert PROTO((tree, tree)); + +/* in c-decl.c */ +/* Standard named or nameless data types of the C compiler. */ +extern tree char_array_type_node; +extern tree char_type_node; +extern tree const_ptr_type_node; +extern tree const_string_type_node; +extern tree default_function_type; +extern tree double_ftype_double; +extern tree double_ftype_double_double; +extern tree double_type_node; +extern tree float_type_node; +extern tree intDI_type_node; +extern tree intHI_type_node; +extern tree intQI_type_node; +extern tree intSI_type_node; +extern tree int_array_type_node; +extern tree int_ftype_cptr_cptr_sizet; +extern tree int_ftype_int; +extern tree int_ftype_ptr_ptr_int; +extern tree int_ftype_string_string; +extern tree integer_type_node; +extern tree long_double_type_node; +extern tree long_ftype_long; +extern tree long_integer_type_node; +extern tree long_long_integer_type_node; +extern tree long_long_unsigned_type_node; +extern tree long_unsigned_type_node; +extern tree complex_integer_type_node; +extern tree complex_float_type_node; +extern tree complex_double_type_node; +extern tree complex_long_double_type_node; +extern tree ptr_type_node; +extern tree ptrdiff_type_node; +extern tree short_integer_type_node; +extern tree short_unsigned_type_node; +extern tree signed_char_type_node; +extern tree signed_wchar_type_node; +extern tree string_ftype_ptr_ptr; +extern tree string_type_node; +extern tree unsigned_char_type_node; +extern tree unsigned_intDI_type_node; +extern tree unsigned_intHI_type_node; +extern tree unsigned_intQI_type_node; +extern tree unsigned_intSI_type_node; +extern tree unsigned_type_node; +extern tree unsigned_wchar_type_node; +extern tree void_ftype_ptr_int_int; +extern tree void_ftype_ptr_ptr_int; +extern tree void_type_node; +extern tree wchar_array_type_node; +extern tree wchar_type_node; + +extern tree build_enumerator PROTO((tree, tree)); +/* Declare a predefined function. Return the declaration. */ +extern tree builtin_function PROTO((char *, tree, enum built_in_function function_, char *)); +/* Add qualifiers to a type, in the fashion for C. */ +extern tree c_build_type_variant PROTO((tree, int, int)); +extern int c_decode_option PROTO((char *)); +extern void c_mark_varargs PROTO((void)); +extern tree check_identifier PROTO((tree, tree)); +extern void clear_parm_order PROTO((void)); +extern tree combine_parm_decls PROTO((tree, tree, int)); +extern int complete_array_type PROTO((tree, tree, int)); +extern void declare_parm_level PROTO((int)); +extern tree define_label PROTO((char *, int, tree)); +extern void delete_block PROTO((tree)); +extern void finish_decl PROTO((tree, tree, tree)); +extern tree finish_enum PROTO((tree, tree)); +extern void finish_function PROTO((int)); +extern tree finish_struct PROTO((tree, tree)); +extern tree get_parm_info PROTO((int)); +extern tree getdecls PROTO((void)); +extern tree gettags PROTO((void)); +extern int global_bindings_p PROTO((void)); +extern tree grokfield PROTO((char *, int, tree, tree, tree)); +extern tree groktypename PROTO((tree)); +extern tree groktypename_in_parm_context PROTO((tree)); +extern tree implicitly_declare PROTO((tree)); +extern int in_parm_level_p PROTO((void)); +extern void init_decl_processing PROTO((void)); +extern void insert_block PROTO((tree)); +extern void keep_next_level PROTO((void)); +extern int kept_level_p PROTO((void)); +extern tree lookup_label PROTO((tree)); +extern tree lookup_name PROTO((tree)); +extern tree lookup_name_current_level PROTO((tree)); +extern tree lookup_name_current_level_global PROTO((tree)); +extern tree maybe_build_cleanup PROTO((tree)); +extern void parmlist_tags_warning PROTO((void)); +extern void pending_xref_error PROTO((void)); +extern void pop_c_function_context PROTO((void)); +extern void pop_label_level PROTO((void)); +extern tree poplevel PROTO((int, int, int)); +extern void print_lang_decl STDIO_PROTO((FILE *, tree, + int)); +extern void print_lang_identifier STDIO_PROTO((FILE *, tree, + int)); +extern void print_lang_type STDIO_PROTO((FILE *, tree, + int)); +extern void push_c_function_context PROTO((void)); +extern void push_label_level PROTO((void)); +extern void push_parm_decl PROTO((tree)); +extern tree pushdecl PROTO((tree)); +extern tree pushdecl_top_level PROTO((tree)); +extern void pushlevel PROTO((int)); +extern void pushtag PROTO((tree, tree)); +extern void set_block PROTO((tree)); +extern tree shadow_label PROTO((tree)); +extern void shadow_record_fields PROTO((tree)); +extern void shadow_tag PROTO((tree)); +extern void shadow_tag_warned PROTO((tree, int)); +extern tree start_enum PROTO((tree)); +extern int start_function PROTO((tree, tree, int)); +extern tree start_decl PROTO((tree, tree, int)); +extern tree start_struct PROTO((enum tree_code, tree)); +extern void store_parm_decls PROTO((void)); +extern tree xref_tag PROTO((enum tree_code, tree)); + +/* in c-typeck.c */ +extern tree require_complete_type PROTO((tree)); +extern void incomplete_type_error PROTO((tree, tree)); +/* Given two integer or real types, return the type for their sum. + Given two compatible ANSI C types, returns the merged type. */ +extern tree common_type PROTO((tree, tree)); +extern int comptypes PROTO((tree, tree)); +extern int self_promoting_args_p PROTO((tree)); +extern tree c_sizeof PROTO((tree)); +extern tree c_sizeof_nowarn PROTO((tree)); +extern tree c_size_in_bytes PROTO((tree)); +extern tree c_alignof PROTO((tree)); +extern tree c_alignof_expr PROTO((tree)); +extern tree default_conversion PROTO((tree)); +extern tree build_component_ref PROTO((tree, tree)); +extern tree build_indirect_ref PROTO((tree, char *)); +extern tree build_array_ref PROTO((tree, tree)); +extern tree build_function_call PROTO((tree, tree)); +extern tree parser_build_binary_op PROTO((enum tree_code, + tree, tree)); +extern tree build_binary_op PROTO((enum tree_code, + tree, tree, int)); +extern tree build_unary_op PROTO((enum tree_code, + tree, int)); +extern int lvalue_p PROTO((tree)); +extern int lvalue_or_else PROTO((tree, char *)); +extern void readonly_warning PROTO((tree, char *)); +extern int mark_addressable PROTO((tree)); +extern tree build_conditional_expr PROTO((tree, tree, tree)); +extern tree build_compound_expr PROTO((tree)); +extern tree build_c_cast PROTO((tree, tree)); +extern tree build_modify_expr PROTO((tree, enum tree_code, + tree)); +extern tree initializer_constant_valid_p PROTO((tree, tree)); +extern void store_init_value PROTO((tree, tree)); +extern void error_init PROTO((char *, char *, + char *)); +extern void pedwarn_init PROTO((char *, char *, + char *)); +extern void start_init PROTO((tree, tree, int)); +extern void finish_init PROTO((void)); +extern void really_start_incremental_init PROTO((tree)); +extern void push_init_level PROTO((int)); +extern tree pop_init_level PROTO((int)); +extern void set_init_index PROTO((tree, tree)); +extern void set_init_label PROTO((tree)); +extern void process_init_element PROTO((tree)); +extern void c_expand_asm_operands PROTO((tree, tree, tree, tree, + int, char *, int)); +extern void c_expand_return PROTO((tree)); +extern tree c_expand_start_case PROTO((tree)); + +/* in c-iterate.c */ +extern void iterator_expand PROTO((tree)); +extern void iterator_for_loop_start PROTO((tree)); +extern void iterator_for_loop_end PROTO((tree)); +extern void iterator_for_loop_record PROTO((tree)); +extern void push_iterator_stack PROTO((void)); +extern void pop_iterator_stack PROTO((void)); + +/* Set to 0 at beginning of a function definition, set to 1 if + a return statement that specifies a return value is seen. */ + +extern int current_function_returns_value; + +/* Set to 0 at beginning of a function definition, set to 1 if + a return statement with no argument is seen. */ + +extern int current_function_returns_null; + +/* Nonzero means `$' can be in an identifier. */ + +extern int dollars_in_ident; + +/* Nonzero means allow type mismatches in conditional expressions; + just make their values `void'. */ + +extern int flag_cond_mismatch; + +/* Nonzero means don't recognize the keyword `asm'. */ + +extern int flag_no_asm; + +/* Nonzero means ignore `#ident' directives. */ + +extern int flag_no_ident; + +/* Nonzero means warn about implicit declarations. */ + +extern int warn_implicit; + +/* Nonzero means give string constants the type `const char *' + to get extra warnings from them. These warnings will be too numerous + to be useful, except in thoroughly ANSIfied programs. */ + +extern int warn_write_strings; + +/* Nonzero means warn about sizeof (function) or addition/subtraction + of function pointers. */ + +extern int warn_pointer_arith; + +/* Nonzero means warn for all old-style non-prototype function decls. */ + +extern int warn_strict_prototypes; + +/* Nonzero means warn about multiple (redundant) decls for the same single + variable or function. */ + +extern int warn_redundant_decls; + +/* Nonzero means warn about extern declarations of objects not at + file-scope level and about *all* declarations of functions (whether + extern or static) not at file-scope level. Note that we exclude + implicit function declarations. To get warnings about those, use + -Wimplicit. */ + +extern int warn_nested_externs; + +/* Nonzero means warn about pointer casts that can drop a type qualifier + from the pointer target type. */ + +extern int warn_cast_qual; + +/* Nonzero means warn when casting a function call to a type that does + not match the return type (e.g. (float)sqrt() or (anything*)malloc() + when there is no previous declaration of sqrt or malloc. */ + +extern int warn_bad_function_cast; + +/* Warn about traditional constructs whose meanings changed in ANSI C. */ + +extern int warn_traditional; + +/* Warn about *printf or *scanf format/argument anomalies. */ + +extern int warn_format; + +/* Warn about a subscript that has type char. */ + +extern int warn_char_subscripts; + +/* Warn if a type conversion is done that might have confusing results. */ + +extern int warn_conversion; + +/* Nonzero means do some things the same way PCC does. */ + +extern int flag_traditional; + +/* Nonzero means to allow single precision math even if we're generally + being traditional. */ +extern int flag_allow_single_precision; + +/* Nonzero means warn about suggesting putting in ()'s. */ + +extern int warn_parentheses; + +/* Warn if initializer is not completely bracketed. */ + +extern int warn_missing_braces; + +/* Nonzero means this is a function to call to perform comptypes + on two record types. */ + +extern int (*comptypes_record_hook) (); + +/* Nonzero means we are reading code that came from a system header file. */ + +extern int system_header_p; + +/* Nonzero enables objc features. */ + +extern int doing_objc_thang; + +#endif /* not _C_TREE_H */ diff --git a/gnu/usr.bin/cc/include/conditions.h b/gnu/usr.bin/cc/include/conditions.h new file mode 100644 index 0000000..e7319377 --- /dev/null +++ b/gnu/usr.bin/cc/include/conditions.h @@ -0,0 +1,115 @@ +/* Definitions for condition code handling in final.c and output routines. + Copyright (C) 1987 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* None of the things in the files exist if we don't use CC0. */ + +#ifdef HAVE_cc0 + +/* The variable cc_status says how to interpret the condition code. + It is set by output routines for an instruction that sets the cc's + and examined by output routines for jump instructions. + + cc_status contains two components named `value1' and `value2' + that record two equivalent expressions for the values that the + condition codes were set from. (Either or both may be null if + there is no useful expression to record.) These fields are + used for eliminating redundant test and compare instructions + in the cases where the condition codes were already set by the + previous instruction. + + cc_status.flags contains flags which say that the condition codes + were set in a nonstandard manner. The output of jump instructions + uses these flags to compensate and produce the standard result + with the nonstandard condition codes. Standard flags are defined here. + The tm.h file can also define other machine-dependent flags. + + cc_status also contains a machine-dependent component `mdep' + whose type, `CC_STATUS_MDEP', may be defined as a macro in the + tm.h file. */ + +#ifndef CC_STATUS_MDEP +#define CC_STATUS_MDEP int +#endif + +#ifndef CC_STATUS_MDEP_INIT +#define CC_STATUS_MDEP_INIT 0 +#endif + +typedef struct {int flags; rtx value1, value2; CC_STATUS_MDEP mdep;} CC_STATUS; + +/* While outputting an insn as assembler code, + this is the status BEFORE that insn. */ +extern CC_STATUS cc_prev_status; + +/* While outputting an insn as assembler code, + this is being altered to the status AFTER that insn. */ +extern CC_STATUS cc_status; + +/* These are the machine-independent flags: */ + +/* Set if the sign of the cc value is inverted: + output a following jump-if-less as a jump-if-greater, etc. */ +#define CC_REVERSED 1 + +/* This bit means that the current setting of the N bit is bogus + and conditional jumps should use the Z bit in its place. + This state obtains when an extraction of a signed single-bit field + or an arithmetic shift right of a byte by 7 bits + is turned into a btst, because btst does not set the N bit. */ +#define CC_NOT_POSITIVE 2 + +/* This bit means that the current setting of the N bit is bogus + and conditional jumps should pretend that the N bit is clear. + Used after extraction of an unsigned bit + or logical shift right of a byte by 7 bits is turned into a btst. + The btst does not alter the N bit, but the result of that shift + or extract is never negative. */ +#define CC_NOT_NEGATIVE 4 + +/* This bit means that the current setting of the overflow flag + is bogus and conditional jumps should pretend there is no overflow. */ +#define CC_NO_OVERFLOW 010 + +/* This bit means that what ought to be in the Z bit + should be tested as the complement of the N bit. */ +#define CC_Z_IN_NOT_N 020 + +/* This bit means that what ought to be in the Z bit + should be tested as the N bit. */ +#define CC_Z_IN_N 040 + +/* Nonzero if we must invert the sense of the following branch, i.e. + change EQ to NE. This is not safe for IEEE floating point operations! + It is intended for use only when a combination of arithmetic + or logical insns can leave the condition codes set in a fortuitous + (though inverted) state. */ +#define CC_INVERTED 0100 + +/* Nonzero if we must convert signed condition operators to unsigned. + This is only used by machine description files. */ +#define CC_NOT_SIGNED 0200 + +/* This is how to initialize the variable cc_status. + final does this at appropriate moments. */ + +#define CC_STATUS_INIT \ + (cc_status.flags = 0, cc_status.value1 = 0, cc_status.value2 = 0, \ + CC_STATUS_MDEP_INIT) + +#endif diff --git a/gnu/usr.bin/cc/include/config.h b/gnu/usr.bin/cc/include/config.h new file mode 100644 index 0000000..7886724 --- /dev/null +++ b/gnu/usr.bin/cc/include/config.h @@ -0,0 +1,42 @@ +/* Configuration for GNU C-compiler for Intel 80386. + Copyright (C) 1988, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef i386 +#define i386 +#endif + +/* #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/gnu/usr.bin/cc/include/convert.h b/gnu/usr.bin/cc/include/convert.h new file mode 100644 index 0000000..b2c8c79 --- /dev/null +++ b/gnu/usr.bin/cc/include/convert.h @@ -0,0 +1,23 @@ +/* Definition of functions in convert.c. + Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +extern tree convert_to_integer PROTO ((tree, tree)); +extern tree convert_to_pointer PROTO ((tree, tree)); +extern tree convert_to_real PROTO ((tree, tree)); +extern tree convert_to_complex PROTO ((tree, tree)); diff --git a/gnu/usr.bin/cc/include/defaults.h b/gnu/usr.bin/cc/include/defaults.h new file mode 100644 index 0000000..df5ce1c --- /dev/null +++ b/gnu/usr.bin/cc/include/defaults.h @@ -0,0 +1,133 @@ +/* Definitions of various defaults for how to do assembler output + (most of which are designed to be appropriate for GAS or for + some BSD assembler). + + Written by Ron Guilmette (rfg@netcom.com) + +Copyright (C) 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Store in OUTPUT a string (made with alloca) containing + an assembler-name for a local static variable or function named NAME. + LABELNO is an integer which is different for each call. */ + +#ifndef ASM_FORMAT_PRIVATE_NAME +#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ + do { \ + int len = strlen (NAME); \ + char *temp = (char *) alloca (len + 3); \ + temp[0] = 'L'; \ + strcpy (&temp[1], (NAME)); \ + temp[len + 1] = '.'; \ + temp[len + 2] = 0; \ + (OUTPUT) = (char *) alloca (strlen (NAME) + 11); \ + ASM_GENERATE_INTERNAL_LABEL (OUTPUT, temp, LABELNO); \ + } while (0) +#endif + +#ifndef ASM_STABD_OP +#define ASM_STABD_OP ".stabd" +#endif + +/* This is how to output an element of a case-vector that is absolute. + Some targets don't use this, but we have to define it anyway. */ + +#ifndef ASM_OUTPUT_ADDR_VEC_ELT +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ +do { fprintf (FILE, "\t%s\t", ASM_LONG); \ + ASM_OUTPUT_INTERNAL_LABEL (FILE, "L", (VALUE)); \ + fputc ('\n', FILE); \ + } while (0) +#endif + +/* This is how to output an element of a case-vector that is relative. + Some targets don't use this, but we have to define it anyway. */ + +#ifndef ASM_OUTPUT_ADDR_DIFF_ELT +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ +do { fprintf (FILE, "\t%s\t", ASM_SHORT); \ + ASM_OUTPUT_INTERNAL_LABEL (FILE, "L", (VALUE)); \ + fputc ('-', FILE); \ + ASM_OUTPUT_INTERNAL_LABEL (FILE, "L", (REL)); \ + fputc ('\n', FILE); \ + } while (0) +#endif + +/* choose a reasonable default for ASM_OUTPUT_ASCII. */ + +#ifndef ASM_OUTPUT_ASCII +#define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \ + do { \ + FILE *_hide_asm_out_file = (MYFILE); \ + unsigned char *_hide_p = (unsigned char *) (MYSTRING); \ + int _hide_thissize = (MYLENGTH); \ + { \ + FILE *asm_out_file = _hide_asm_out_file; \ + unsigned char *p = _hide_p; \ + int thissize = _hide_thissize; \ + int i; \ + fprintf (asm_out_file, "\t.ascii \""); \ + \ + for (i = 0; i < thissize; i++) \ + { \ + register int c = p[i]; \ + if (c == '\"' || c == '\\') \ + putc ('\\', asm_out_file); \ + if (c >= ' ' && c < 0177) \ + putc (c, asm_out_file); \ + else \ + { \ + fprintf (asm_out_file, "\\%o", c); \ + /* After an octal-escape, if a digit follows, \ + terminate one string constant and start another. \ + The Vax assembler fails to stop reading the escape \ + after three digits, so this is the only way we \ + can get it to parse the data properly. */ \ + if (i < thissize - 1 \ + && p[i + 1] >= '0' && p[i + 1] <= '9') \ + fprintf (asm_out_file, "\"\n\t.ascii \""); \ + } \ + } \ + fprintf (asm_out_file, "\"\n"); \ + } \ + } \ + while (0) +#endif + +#ifndef ASM_IDENTIFY_GCC + /* Default the definition, only if ASM_IDENTIFY_GCC is not set, + because if it is set, we might not want ASM_IDENTIFY_LANGUAGE + outputting labels, if we do want it to, then it must be defined + in the tm.h file. */ +#ifndef ASM_IDENTIFY_LANGUAGE +#define ASM_IDENTIFY_LANGUAGE(FILE) output_lang_identify (FILE); +#endif +#endif + +/* This is how we tell the assembler to equate two values. */ +#ifdef SET_ASM_OP +#ifndef ASM_OUTPUT_DEF +#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ + do { fprintf ((FILE), "\t%s\t", SET_ASM_OP); \ + assemble_name (FILE, LABEL1); \ + fprintf (FILE, ","); \ + assemble_name (FILE, LABEL2); \ + fprintf (FILE, "\n"); \ + } while (0) +#endif +#endif diff --git a/gnu/usr.bin/cc/include/expr.h b/gnu/usr.bin/cc/include/expr.h new file mode 100644 index 0000000..3bb9490 --- /dev/null +++ b/gnu/usr.bin/cc/include/expr.h @@ -0,0 +1,834 @@ +/* Definitions for code generation pass of GNU compiler. + Copyright (C) 1987, 1991, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +#ifndef __STDC__ +#ifndef const +#define const +#endif +#endif + +/* The default branch cost is 1. */ +#ifndef BRANCH_COST +#define BRANCH_COST 1 +#endif + +/* Macros to access the slots of a QUEUED rtx. + Here rather than in rtl.h because only the expansion pass + should ever encounter a QUEUED. */ + +/* The variable for which an increment is queued. */ +#define QUEUED_VAR(P) XEXP (P, 0) +/* If the increment has been emitted, this is the insn + that does the increment. It is zero before the increment is emitted. */ +#define QUEUED_INSN(P) XEXP (P, 1) +/* If a pre-increment copy has been generated, this is the copy + (it is a temporary reg). Zero if no copy made yet. */ +#define QUEUED_COPY(P) XEXP (P, 2) +/* This is the body to use for the insn to do the increment. + It is used to emit the increment. */ +#define QUEUED_BODY(P) XEXP (P, 3) +/* Next QUEUED in the queue. */ +#define QUEUED_NEXT(P) XEXP (P, 4) + +/* This is the 4th arg to `expand_expr'. + EXPAND_SUM means it is ok to return a PLUS rtx or MULT rtx. + EXPAND_INITIALIZER is similar but also record any labels on forced_labels. + EXPAND_CONST_ADDRESS means it is ok to return a MEM whose address + is a constant that is not a legitimate address. */ +enum expand_modifier {EXPAND_NORMAL, EXPAND_SUM, + EXPAND_CONST_ADDRESS, EXPAND_INITIALIZER}; + +/* List of labels that must never be deleted. */ +extern rtx forced_labels; + +/* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs. + So we can mark them all live at the end of the function, if stupid. */ +extern rtx save_expr_regs; + +extern int current_function_calls_alloca; +extern int current_function_outgoing_args_size; + +/* This is the offset from the arg pointer to the place where the first + anonymous arg can be found, if there is one. */ +extern rtx current_function_arg_offset_rtx; + +/* This is nonzero if the current function uses the constant pool. */ +extern int current_function_uses_const_pool; + +/* This is nonzero if the current function uses pic_offset_table_rtx. */ +extern int current_function_uses_pic_offset_table; + +/* The arg pointer hard register, or the pseudo into which it was copied. */ +extern rtx current_function_internal_arg_pointer; + +/* Nonzero means stack pops must not be deferred, and deferred stack + pops must not be output. It is nonzero inside a function call, + inside a conditional expression, inside a statement expression, + and in other cases as well. */ +extern int inhibit_defer_pop; + +/* Number of function calls seen so far in current function. */ + +extern int function_call_count; + +/* RTX for stack slot that holds the current handler for nonlocal gotos. + Zero when function does not have nonlocal labels. */ + +extern rtx nonlocal_goto_handler_slot; + +/* RTX for stack slot that holds the stack pointer value to restore + for a nonlocal goto. + Zero when function does not have nonlocal labels. */ + +extern rtx nonlocal_goto_stack_level; + +/* List (chain of TREE_LIST) of LABEL_DECLs for all nonlocal labels + (labels to which there can be nonlocal gotos from nested functions) + in this function. */ + +#ifdef TREE_CODE /* Don't lose if tree.h not included. */ +extern tree nonlocal_labels; +#endif + +#define NO_DEFER_POP (inhibit_defer_pop += 1) +#define OK_DEFER_POP (inhibit_defer_pop -= 1) + +/* Number of units that we should eventually pop off the stack. + These are the arguments to function calls that have already returned. */ +extern int pending_stack_adjust; + +/* A list of all cleanups which belong to the arguments of + function calls being expanded by expand_call. */ +#ifdef TREE_CODE /* Don't lose if tree.h not included. */ +extern tree cleanups_this_call; +#endif + +/* When temporaries are created by TARGET_EXPRs, they are created at + this level of temp_slot_level, so that they can remain allocated + until no longer needed. CLEANUP_POINT_EXPRs define the lifetime + of TARGET_EXPRs. */ +extern int target_temp_slot_level; + +#ifdef TREE_CODE /* Don't lose if tree.h not included. */ +/* Structure to record the size of a sequence of arguments + as the sum of a tree-expression and a constant. */ + +struct args_size +{ + int constant; + tree var; +}; +#endif + +/* Add the value of the tree INC to the `struct args_size' TO. */ + +#define ADD_PARM_SIZE(TO, INC) \ +{ tree inc = (INC); \ + if (TREE_CODE (inc) == INTEGER_CST) \ + (TO).constant += TREE_INT_CST_LOW (inc); \ + else if ((TO).var == 0) \ + (TO).var = inc; \ + else \ + (TO).var = size_binop (PLUS_EXPR, (TO).var, inc); } + +#define SUB_PARM_SIZE(TO, DEC) \ +{ tree dec = (DEC); \ + if (TREE_CODE (dec) == INTEGER_CST) \ + (TO).constant -= TREE_INT_CST_LOW (dec); \ + else if ((TO).var == 0) \ + (TO).var = size_binop (MINUS_EXPR, integer_zero_node, dec); \ + else \ + (TO).var = size_binop (MINUS_EXPR, (TO).var, dec); } + +/* Convert the implicit sum in a `struct args_size' into an rtx. */ +#define ARGS_SIZE_RTX(SIZE) \ +((SIZE).var == 0 ? GEN_INT ((SIZE).constant) \ + : expand_expr (size_binop (PLUS_EXPR, (SIZE).var, \ + size_int ((SIZE).constant)), \ + NULL_RTX, VOIDmode, 0)) + +/* Convert the implicit sum in a `struct args_size' into a tree. */ +#define ARGS_SIZE_TREE(SIZE) \ +((SIZE).var == 0 ? size_int ((SIZE).constant) \ + : size_binop (PLUS_EXPR, (SIZE).var, size_int ((SIZE).constant))) + +/* Supply a default definition for FUNCTION_ARG_PADDING: + usually pad upward, but pad short args downward on + big-endian machines. */ + +enum direction {none, upward, downward}; /* Value has this type. */ + +#ifndef FUNCTION_ARG_PADDING +#if BYTES_BIG_ENDIAN +#define FUNCTION_ARG_PADDING(MODE, TYPE) \ + (((MODE) == BLKmode \ + ? ((TYPE) && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \ + && int_size_in_bytes (TYPE) < (PARM_BOUNDARY / BITS_PER_UNIT)) \ + : GET_MODE_BITSIZE (MODE) < PARM_BOUNDARY) \ + ? downward : upward) +#else +#define FUNCTION_ARG_PADDING(MODE, TYPE) upward +#endif +#endif + +/* Supply a default definition for FUNCTION_ARG_BOUNDARY. Normally, we let + FUNCTION_ARG_PADDING, which also pads the length, handle any needed + alignment. */ + +#ifndef FUNCTION_ARG_BOUNDARY +#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) PARM_BOUNDARY +#endif + +/* Nonzero if we do not know how to pass TYPE solely in registers. + We cannot do so in the following cases: + + - if the type has variable size + - if the type is marked as addressable (it is required to be constructed + into the stack) + - if the padding and mode of the type is such that a copy into a register + would put it into the wrong part of the register. + + Which padding can't be supported depends on the byte endianness. + + A value in a register is implicitly padded at the most significant end. + On a big-endian machine, that is the lower end in memory. + So a value padded in memory at the upper end can't go in a register. + For a little-endian machine, the reverse is true. */ + +#if BYTES_BIG_ENDIAN +#define MUST_PASS_IN_STACK_BAD_PADDING upward +#else +#define MUST_PASS_IN_STACK_BAD_PADDING downward +#endif + +#define MUST_PASS_IN_STACK(MODE,TYPE) \ + ((TYPE) != 0 \ + && (TREE_CODE (TYPE_SIZE (TYPE)) != INTEGER_CST \ + || TREE_ADDRESSABLE (TYPE) \ + || ((MODE) == BLKmode \ + && ! ((TYPE) != 0 && TREE_CODE (TYPE_SIZE (TYPE)) == INTEGER_CST \ + && 0 == (int_size_in_bytes (TYPE) \ + % (PARM_BOUNDARY / BITS_PER_UNIT))) \ + && (FUNCTION_ARG_PADDING (MODE, TYPE) \ + == MUST_PASS_IN_STACK_BAD_PADDING)))) + +/* Nonzero if type TYPE should be returned in memory. + Most machines can use the following default definition. */ + +#ifndef RETURN_IN_MEMORY +#define RETURN_IN_MEMORY(TYPE) (TYPE_MODE (TYPE) == BLKmode) +#endif + +/* Optabs are tables saying how to generate insn bodies + for various machine modes and numbers of operands. + Each optab applies to one operation. + For example, add_optab applies to addition. + + The insn_code slot is the enum insn_code that says how to + generate an insn for this operation on a particular machine mode. + It is CODE_FOR_nothing if there is no such insn on the target machine. + + The `lib_call' slot is the name of the library function that + can be used to perform the operation. + + A few optabs, such as move_optab and cmp_optab, are used + by special code. */ + +/* Everything that uses expr.h needs to define enum insn_code + but we don't list it in the Makefile dependencies just for that. */ +#include "insn-codes.h" + +typedef struct optab +{ + enum rtx_code code; + struct { + enum insn_code insn_code; + rtx libfunc; + } handlers [NUM_MACHINE_MODES]; +} * optab; + +/* Given an enum insn_code, access the function to construct + the body of that kind of insn. */ +#ifdef FUNCTION_CONVERSION_BUG +/* Some compilers fail to convert a function properly to a + pointer-to-function when used as an argument. + So produce the pointer-to-function directly. + Luckily, these compilers seem to work properly when you + call the pointer-to-function. */ +#define GEN_FCN(CODE) (insn_gen_function[(int) (CODE)]) +#else +#define GEN_FCN(CODE) (*insn_gen_function[(int) (CODE)]) +#endif + +extern rtx (*const insn_gen_function[]) (); + +extern optab add_optab; +extern optab sub_optab; +extern optab smul_optab; /* Signed and floating-point multiply */ +extern optab smul_highpart_optab; /* Signed multiply, return high word */ +extern optab umul_highpart_optab; +extern optab smul_widen_optab; /* Signed multiply with result + one machine mode wider than args */ +extern optab umul_widen_optab; +extern optab sdiv_optab; /* Signed divide */ +extern optab sdivmod_optab; /* Signed divide-and-remainder in one */ +extern optab udiv_optab; +extern optab udivmod_optab; +extern optab smod_optab; /* Signed remainder */ +extern optab umod_optab; +extern optab flodiv_optab; /* Optab for floating divide. */ +extern optab ftrunc_optab; /* Convert float to integer in float fmt */ +extern optab and_optab; /* Logical and */ +extern optab ior_optab; /* Logical or */ +extern optab xor_optab; /* Logical xor */ +extern optab ashl_optab; /* Arithmetic shift left */ +extern optab ashr_optab; /* Arithmetic shift right */ +extern optab lshr_optab; /* Logical shift right */ +extern optab rotl_optab; /* Rotate left */ +extern optab rotr_optab; /* Rotate right */ +extern optab smin_optab; /* Signed and floating-point minimum value */ +extern optab smax_optab; /* Signed and floating-point maximum value */ +extern optab umin_optab; /* Unsigned minimum value */ +extern optab umax_optab; /* Unsigned maximum value */ + +extern optab mov_optab; /* Move instruction. */ +extern optab movstrict_optab; /* Move, preserving high part of register. */ + +extern optab cmp_optab; /* Compare insn; two operands. */ +extern optab tst_optab; /* tst insn; compare one operand against 0 */ + +/* Unary operations */ +extern optab neg_optab; /* Negation */ +extern optab abs_optab; /* Abs value */ +extern optab one_cmpl_optab; /* Bitwise not */ +extern optab ffs_optab; /* Find first bit set */ +extern optab sqrt_optab; /* Square root */ +extern optab sin_optab; /* Sine */ +extern optab cos_optab; /* Cosine */ +extern optab strlen_optab; /* String length */ + +/* Tables of patterns for extending one integer mode to another. */ +extern enum insn_code extendtab[MAX_MACHINE_MODE][MAX_MACHINE_MODE][2]; + +/* Tables of patterns for converting between fixed and floating point. */ +extern enum insn_code fixtab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; +extern enum insn_code fixtrunctab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; +extern enum insn_code floattab[NUM_MACHINE_MODES][NUM_MACHINE_MODES][2]; + +/* Contains the optab used for each rtx code. */ +extern optab code_to_optab[NUM_RTX_CODE + 1]; + +/* Passed to expand_binop and expand_unop to say which options to try to use + if the requested operation can't be open-coded on the requisite mode. + Either OPTAB_LIB or OPTAB_LIB_WIDEN says try using a library call. + Either OPTAB_WIDEN or OPTAB_LIB_WIDEN says try using a wider mode. + OPTAB_MUST_WIDEN says try widening and don't try anything else. */ + +enum optab_methods +{ + OPTAB_DIRECT, + OPTAB_LIB, + OPTAB_WIDEN, + OPTAB_LIB_WIDEN, + OPTAB_MUST_WIDEN +}; + +/* SYMBOL_REF rtx's for the library functions that are called + implicitly and not via optabs. */ + +extern rtx extendsfdf2_libfunc; +extern rtx extendsfxf2_libfunc; +extern rtx extendsftf2_libfunc; +extern rtx extenddfxf2_libfunc; +extern rtx extenddftf2_libfunc; + +extern rtx truncdfsf2_libfunc; +extern rtx truncxfsf2_libfunc; +extern rtx trunctfsf2_libfunc; +extern rtx truncxfdf2_libfunc; +extern rtx trunctfdf2_libfunc; + +extern rtx memcpy_libfunc; +extern rtx bcopy_libfunc; +extern rtx memcmp_libfunc; +extern rtx bcmp_libfunc; +extern rtx memset_libfunc; +extern rtx bzero_libfunc; + +extern rtx eqsf2_libfunc; +extern rtx nesf2_libfunc; +extern rtx gtsf2_libfunc; +extern rtx gesf2_libfunc; +extern rtx ltsf2_libfunc; +extern rtx lesf2_libfunc; + +extern rtx eqdf2_libfunc; +extern rtx nedf2_libfunc; +extern rtx gtdf2_libfunc; +extern rtx gedf2_libfunc; +extern rtx ltdf2_libfunc; +extern rtx ledf2_libfunc; + +extern rtx eqxf2_libfunc; +extern rtx nexf2_libfunc; +extern rtx gtxf2_libfunc; +extern rtx gexf2_libfunc; +extern rtx ltxf2_libfunc; +extern rtx lexf2_libfunc; + +extern rtx eqtf2_libfunc; +extern rtx netf2_libfunc; +extern rtx gttf2_libfunc; +extern rtx getf2_libfunc; +extern rtx lttf2_libfunc; +extern rtx letf2_libfunc; + +extern rtx floatsisf_libfunc; +extern rtx floatdisf_libfunc; +extern rtx floattisf_libfunc; + +extern rtx floatsidf_libfunc; +extern rtx floatdidf_libfunc; +extern rtx floattidf_libfunc; + +extern rtx floatsixf_libfunc; +extern rtx floatdixf_libfunc; +extern rtx floattixf_libfunc; + +extern rtx floatsitf_libfunc; +extern rtx floatditf_libfunc; +extern rtx floattitf_libfunc; + +extern rtx fixsfsi_libfunc; +extern rtx fixsfdi_libfunc; +extern rtx fixsfti_libfunc; + +extern rtx fixdfsi_libfunc; +extern rtx fixdfdi_libfunc; +extern rtx fixdfti_libfunc; + +extern rtx fixxfsi_libfunc; +extern rtx fixxfdi_libfunc; +extern rtx fixxfti_libfunc; + +extern rtx fixtfsi_libfunc; +extern rtx fixtfdi_libfunc; +extern rtx fixtfti_libfunc; + +extern rtx fixunssfsi_libfunc; +extern rtx fixunssfdi_libfunc; +extern rtx fixunssfti_libfunc; + +extern rtx fixunsdfsi_libfunc; +extern rtx fixunsdfdi_libfunc; +extern rtx fixunsdfti_libfunc; + +extern rtx fixunsxfsi_libfunc; +extern rtx fixunsxfdi_libfunc; +extern rtx fixunsxfti_libfunc; + +extern rtx fixunstfsi_libfunc; +extern rtx fixunstfdi_libfunc; +extern rtx fixunstfti_libfunc; + +typedef rtx (*rtxfun) (); + +/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) + gives the gen_function to make a branch to test that condition. */ + +extern rtxfun bcc_gen_fctn[NUM_RTX_CODE]; + +/* Indexed by the rtx-code for a conditional (eg. EQ, LT,...) + gives the insn code to make a store-condition insn + to test that condition. */ + +extern enum insn_code setcc_gen_code[NUM_RTX_CODE]; + +/* This array records the insn_code of insns to perform block moves. */ +extern enum insn_code movstr_optab[NUM_MACHINE_MODES]; + +/* Define functions given in optabs.c. */ + +/* Expand a binary operation given optab and rtx operands. */ +extern rtx expand_binop PROTO((enum machine_mode, optab, rtx, rtx, rtx, + int, enum optab_methods)); + +/* Expand a binary operation with both signed and unsigned forms. */ +extern rtx sign_expand_binop PROTO((enum machine_mode, optab, optab, rtx, + rtx, rtx, int, enum optab_methods)); + +/* Generate code to perform an operation on two operands with two results. */ +extern int expand_twoval_binop PROTO((optab, rtx, rtx, rtx, rtx, int)); + +/* Expand a unary arithmetic operation given optab rtx operand. */ +extern rtx expand_unop PROTO((enum machine_mode, optab, rtx, rtx, int)); + +/* Expand the complex absolute value operation. */ +extern rtx expand_complex_abs PROTO((enum machine_mode, rtx, rtx, int)); + +/* Generate an instruction with a given INSN_CODE with an output and + an input. */ +extern void emit_unop_insn PROTO((int, rtx, rtx, enum rtx_code)); + +/* Emit code to perform a series of operations on a multi-word quantity, one + word at a time. */ +extern rtx emit_no_conflict_block PROTO((rtx, rtx, rtx, rtx, rtx)); + +/* Emit code to make a call to a constant function or a library call. */ +extern void emit_libcall_block PROTO((rtx, rtx, rtx, rtx)); + +/* Emit one rtl instruction to store zero in specified rtx. */ +extern void emit_clr_insn PROTO((rtx)); + +/* Emit one rtl insn to store 1 in specified rtx assuming it contains 0. */ +extern void emit_0_to_1_insn PROTO((rtx)); + +/* Emit one rtl insn to compare two rtx's. */ +extern void emit_cmp_insn PROTO((rtx, rtx, enum rtx_code, rtx, + enum machine_mode, int, int)); + +/* Nonzero if a compare of mode MODE can be done straightforwardly + (without splitting it into pieces). */ +extern int can_compare_p PROTO((enum machine_mode)); + +/* Emit a library call comparison between floating point X and Y. + COMPARISON is the rtl operator to compare with (EQ, NE, GT, etc.). */ +extern void emit_float_lib_cmp PROTO((rtx, rtx, enum rtx_code)); + +/* Generate code to indirectly jump to a location given in the rtx LOC. */ +extern void emit_indirect_jump PROTO((rtx)); + +/* Create but don't emit one rtl instruction to add one rtx into another. + Modes must match; operands must meet the operation's predicates. + Likewise for subtraction and for just copying. + These do not call protect_from_queue; caller must do so. */ +extern rtx gen_add2_insn PROTO((rtx, rtx)); +extern rtx gen_sub2_insn PROTO((rtx, rtx)); +extern rtx gen_move_insn PROTO((rtx, rtx)); +extern int have_add2_insn PROTO((enum machine_mode)); +extern int have_sub2_insn PROTO((enum machine_mode)); + +/* Return the INSN_CODE to use for an extend operation. */ +extern enum insn_code can_extend_p PROTO((enum machine_mode, + enum machine_mode, int)); + +/* Generate the body of an insn to extend Y (with mode MFROM) + into X (with mode MTO). Do zero-extension if UNSIGNEDP is nonzero. */ +extern rtx gen_extend_insn PROTO((rtx, rtx, enum machine_mode, + enum machine_mode, int)); + +/* Initialize the tables that control conversion between fixed and + floating values. */ +extern void init_fixtab PROTO((void)); +extern void init_floattab PROTO((void)); + +/* Generate code for a FLOAT_EXPR. */ +extern void expand_float PROTO((rtx, rtx, int)); + +/* Generate code for a FIX_EXPR. */ +extern void expand_fix PROTO((rtx, rtx, int)); + +/* Call this once to initialize the contents of the optabs + appropriately for the current target machine. */ +extern void init_optabs PROTO((void)); + +/* Functions from expmed.c: */ + +/* Arguments MODE, RTX: return an rtx for the negation of that value. + May emit insns. */ +extern rtx negate_rtx PROTO((enum machine_mode, rtx)); + +/* Expand a logical AND operation. */ +extern rtx expand_and PROTO((rtx, rtx, rtx)); + +/* Emit a store-flag operation. */ +extern rtx emit_store_flag PROTO((rtx, enum rtx_code, rtx, rtx, + enum machine_mode, int, int)); + +/* Functions from loop.c: */ + +/* Given a JUMP_INSN, return a description of the test being made. */ +extern rtx get_condition PROTO((rtx, rtx *)); + +/* Functions from expr.c: */ + +/* This is run once per compilation to set up which modes can be used + directly in memory and to initialize the block move optab. */ +extern void init_expr_once PROTO((void)); + +/* This is run at the start of compiling a function. */ +extern void init_expr PROTO((void)); + +/* Use protect_from_queue to convert a QUEUED expression + into something that you can put immediately into an instruction. */ +extern rtx protect_from_queue PROTO((rtx, int)); + +/* Perform all the pending incrementations. */ +extern void emit_queue PROTO((void)); + +/* Emit some rtl insns to move data between rtx's, converting machine modes. + Both modes must be floating or both fixed. */ +extern void convert_move PROTO((rtx, rtx, int)); + +/* Convert an rtx to specified machine mode and return the result. */ +extern rtx convert_to_mode PROTO((enum machine_mode, rtx, int)); + +/* Convert an rtx to MODE from OLDMODE and return the result. */ +extern rtx convert_modes PROTO((enum machine_mode, enum machine_mode, rtx, int)); + +/* Emit code to move a block Y to a block X. */ +extern void emit_block_move PROTO((rtx, rtx, rtx, int)); + +/* Copy all or part of a value X into registers starting at REGNO. + The number of registers to be filled is NREGS. */ +extern void move_block_to_reg PROTO((int, rtx, int, enum machine_mode)); + +/* Copy all or part of a BLKmode value X out of registers starting at REGNO. + The number of registers to be filled is NREGS. */ +extern void move_block_from_reg PROTO((int, rtx, int, int)); + +/* Mark REG as holding a parameter for the next CALL_INSN. */ +extern void use_reg PROTO((rtx*, rtx)); +/* Mark NREGS consecutive regs, starting at REGNO, as holding parameters + for the next CALL_INSN. */ +extern void use_regs PROTO((rtx*, int, int)); + +/* Write zeros through the storage of OBJECT. + If OBJECT has BLKmode, SIZE is its length in bytes. */ +extern void clear_storage PROTO((rtx, int)); + +/* Emit insns to set X from Y. */ +extern rtx emit_move_insn PROTO((rtx, rtx)); + +/* Emit insns to set X from Y, with no frills. */ +extern rtx emit_move_insn_1 PROTO ((rtx, rtx)); + +/* Push a block of length SIZE (perhaps variable) + and return an rtx to address the beginning of the block. */ +extern rtx push_block PROTO((rtx, int, int)); + +/* Make an operand to push someting on the stack. */ +extern rtx gen_push_operand PROTO((void)); + +#ifdef TREE_CODE +/* Generate code to push something onto the stack, given its mode and type. */ +extern void emit_push_insn PROTO((rtx, enum machine_mode, tree, rtx, int, + int, rtx, int, rtx, rtx)); + +/* Emit library call. */ +extern void emit_library_call PVPROTO((rtx orgfun, int no_queue, + enum machine_mode outmode, int nargs, ...)); +extern rtx emit_library_call_value PVPROTO((rtx orgfun, rtx value, int no_queue, + enum machine_mode outmode, int nargs, ...)); + +/* Expand an assignment that stores the value of FROM into TO. */ +extern rtx expand_assignment PROTO((tree, tree, int, int)); + +/* Generate code for computing expression EXP, + and storing the value into TARGET. + If SUGGEST_REG is nonzero, copy the value through a register + and return that register, if that is possible. */ +extern rtx store_expr PROTO((tree, rtx, int)); +#endif + +/* Given an rtx that may include add and multiply operations, + generate them as insns and return a pseudo-reg containing the value. + Useful after calling expand_expr with 1 as sum_ok. */ +extern rtx force_operand PROTO((rtx, rtx)); + +#ifdef TREE_CODE +/* Generate code for computing expression EXP. + An rtx for the computed value is returned. The value is never null. + In the case of a void EXP, const0_rtx is returned. */ +extern rtx expand_expr PROTO((tree, rtx, enum machine_mode, + enum expand_modifier)); +#endif + +/* At the start of a function, record that we have no previously-pushed + arguments waiting to be popped. */ +extern void init_pending_stack_adjust PROTO((void)); + +/* When exiting from function, if safe, clear out any pending stack adjust + so the adjustment won't get done. */ +extern void clear_pending_stack_adjust PROTO((void)); + +/* Pop any previously-pushed arguments that have not been popped yet. */ +extern void do_pending_stack_adjust PROTO((void)); + +#ifdef TREE_CODE +/* Expand all cleanups up to OLD_CLEANUPS. */ +extern void expand_cleanups_to PROTO((tree)); + +/* Generate code to evaluate EXP and jump to LABEL if the value is zero. */ +extern void jumpifnot PROTO((tree, rtx)); + +/* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */ +extern void jumpif PROTO((tree, rtx)); + +/* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if + the result is zero, or IF_TRUE_LABEL if the result is one. */ +extern void do_jump PROTO((tree, rtx, rtx)); +#endif + +/* Generate rtl to compare two rtx's, will call emit_cmp_insn. */ +extern rtx compare_from_rtx PROTO((rtx, rtx, enum rtx_code, int, + enum machine_mode, rtx, int)); + +/* Generate a tablejump instruction (used for switch statements). */ +extern void do_tablejump PROTO((rtx, enum machine_mode, rtx, rtx, rtx)); + +#ifdef TREE_CODE +/* rtl.h and tree.h were included. */ +/* Return an rtx for the size in bytes of the value of an expr. */ +extern rtx expr_size PROTO((tree)); + +extern rtx lookup_static_chain PROTO((tree)); + +/* Convert a stack slot address ADDR valid in function FNDECL + into an address valid in this function (using a static chain). */ +extern rtx fix_lexical_addr PROTO((rtx, tree)); + +/* Return the address of the trampoline for entering nested fn FUNCTION. */ +extern rtx trampoline_address PROTO((tree)); + +/* Return an rtx that refers to the value returned by a function + in its original home. This becomes invalid if any more code is emitted. */ +extern rtx hard_function_value PROTO((tree, tree)); + +extern rtx prepare_call_address PROTO((rtx, tree, rtx *, int)); + +extern rtx expand_call PROTO((tree, rtx, int)); + +extern rtx expand_shift PROTO((enum tree_code, enum machine_mode, rtx, tree, rtx, int)); +extern rtx expand_divmod PROTO((int, enum tree_code, enum machine_mode, rtx, rtx, rtx, int)); +extern void locate_and_pad_parm PROTO((enum machine_mode, tree, int, tree, struct args_size *, struct args_size *, struct args_size *)); +extern rtx expand_inline_function PROTO((tree, tree, rtx, int, tree, rtx)); +/* Return the CODE_LABEL rtx for a LABEL_DECL, creating it if necessary. */ +extern rtx label_rtx PROTO((tree)); +#endif + +/* Indicate how an input argument register was promoted. */ +extern rtx promoted_input_arg PROTO((int, enum machine_mode *, int *)); + +/* Return an rtx like arg but sans any constant terms. + Returns the original rtx if it has no constant terms. + The constant terms are added and stored via a second arg. */ +extern rtx eliminate_constant_term PROTO((rtx, rtx *)); + +/* Convert arg to a valid memory address for specified machine mode, + by emitting insns to perform arithmetic if nec. */ +extern rtx memory_address PROTO((enum machine_mode, rtx)); + +/* Like `memory_address' but pretent `flag_force_addr' is 0. */ +extern rtx memory_address_noforce PROTO((enum machine_mode, rtx)); + +/* Return a memory reference like MEMREF, but with its mode changed + to MODE and its address changed to ADDR. + (VOIDmode means don't change the mode. + NULL for ADDR means don't change the address.) */ +extern rtx change_address PROTO((rtx, enum machine_mode, rtx)); + +/* Return a memory reference like MEMREF, but which is known to have a + valid address. */ + +extern rtx validize_mem PROTO((rtx)); + +/* Assemble the static constant template for function entry trampolines. */ +extern rtx assemble_trampoline_template PROTO((void)); + +/* Return 1 if two rtx's are equivalent in structure and elements. */ +extern int rtx_equal_p PROTO((rtx, rtx)); + +/* Given rtx, return new rtx whose address won't be affected by + any side effects. It has been copied to a new temporary reg. */ +extern rtx stabilize PROTO((rtx)); + +/* Given an rtx, copy all regs it refers to into new temps + and return a modified copy that refers to the new temps. */ +extern rtx copy_all_regs PROTO((rtx)); + +/* Copy given rtx to a new temp reg and return that. */ +extern rtx copy_to_reg PROTO((rtx)); + +/* Like copy_to_reg but always make the reg Pmode. */ +extern rtx copy_addr_to_reg PROTO((rtx)); + +/* Like copy_to_reg but always make the reg the specified mode MODE. */ +extern rtx copy_to_mode_reg PROTO((enum machine_mode, rtx)); + +/* Copy given rtx to given temp reg and return that. */ +extern rtx copy_to_suggested_reg PROTO((rtx, rtx, enum machine_mode)); + +/* Copy a value to a register if it isn't already a register. + Args are mode (in case value is a constant) and the value. */ +extern rtx force_reg PROTO((enum machine_mode, rtx)); + +/* Return given rtx, copied into a new temp reg if it was in memory. */ +extern rtx force_not_mem PROTO((rtx)); + +#ifdef TREE_CODE +/* Return mode and signedness to use when object is promoted. */ +extern enum machine_mode promote_mode PROTO((tree, enum machine_mode, + int *, int)); +#endif + +/* Remove some bytes from the stack. An rtx says how many. */ +extern void adjust_stack PROTO((rtx)); + +/* Add some bytes to the stack. An rtx says how many. */ +extern void anti_adjust_stack PROTO((rtx)); + +/* This enum is used for the following two functions. */ +enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL}; + +/* Save the stack pointer at the specified level. */ +extern void emit_stack_save PROTO((enum save_level, rtx *, rtx)); + +/* Restore the stack pointer from a save area of the specified level. */ +extern void emit_stack_restore PROTO((enum save_level, rtx, rtx)); + +/* Allocate some space on the stack dynamically and return its address. An rtx + says how many bytes. */ +extern rtx allocate_dynamic_stack_space PROTO((rtx, rtx, int)); + +/* Emit code to copy function value to a new temp reg and return that reg. */ +extern rtx function_value (); + +/* Return an rtx that refers to the value returned by a library call + in its original home. This becomes invalid if any more code is emitted. */ +extern rtx hard_libcall_value PROTO((enum machine_mode)); + +/* Given an rtx, return an rtx for a value rounded up to a multiple + of STACK_BOUNDARY / BITS_PER_UNIT. */ +extern rtx round_push PROTO((rtx)); + +extern void emit_block_move PROTO((rtx, rtx, rtx, int)); + +extern rtx store_bit_field PROTO((rtx, int, int, enum machine_mode, rtx, int, int)); +extern rtx extract_bit_field PROTO((rtx, int, int, int, rtx, enum machine_mode, enum machine_mode, int, int)); +extern rtx expand_mult PROTO((enum machine_mode, rtx, rtx, rtx, int)); +extern rtx expand_mult_add PROTO((rtx, rtx, rtx, rtx,enum machine_mode, int)); + +extern rtx assemble_static_space PROTO((int)); + +/* Hook called by expand_expr for language-specific tree codes. + It is up to the language front end to install a hook + if it has any such codes that expand_expr needs to know about. */ +extern rtx (*lang_expand_expr) (); diff --git a/gnu/usr.bin/cc/include/flags.h b/gnu/usr.bin/cc/include/flags.h new file mode 100644 index 0000000..07ea734 --- /dev/null +++ b/gnu/usr.bin/cc/include/flags.h @@ -0,0 +1,359 @@ +/* Compilation switch flag definitions for GNU CC. + Copyright (C) 1987, 1988, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Name of the input .c file being compiled. */ +extern char *main_input_filename; + +enum debug_info_type +{ + NO_DEBUG, /* Write no debug info. */ + DBX_DEBUG, /* Write BSD .stabs for DBX (using dbxout.c). */ + SDB_DEBUG, /* Write COFF for (old) SDB (using sdbout.c). */ + DWARF_DEBUG, /* Write Dwarf debug info (using dwarfout.c). */ + XCOFF_DEBUG /* Write IBM/Xcoff debug info (using dbxout.c). */ +}; + +/* Specify which kind of debugging info to generate. */ +extern enum debug_info_type write_symbols; + +enum debug_info_level +{ + DINFO_LEVEL_NONE, /* Write no debugging info. */ + DINFO_LEVEL_TERSE, /* Write minimal info to support tracebacks only. */ + DINFO_LEVEL_NORMAL, /* Write info for all declarations (and line table). */ + DINFO_LEVEL_VERBOSE /* Write normal info plus #define/#undef info. */ +}; + +/* Specify how much debugging info to generate. */ +extern enum debug_info_level debug_info_level; + +/* Nonzero means use GNU-only extensions in the generated symbolic + debugging information. */ +extern int use_gnu_debug_info_extensions; + +/* Nonzero means do optimizations. -opt. */ + +extern int optimize; + +/* Nonzero means do stupid register allocation. -noreg. + Currently, this is 1 if `optimize' is 0. */ + +extern int obey_regdecls; + +/* Don't print functions as they are compiled and don't print + times taken by the various passes. -quiet. */ + +extern int quiet_flag; + +/* Don't print warning messages. -w. */ + +extern int inhibit_warnings; + +/* Do print extra warnings (such as for uninitialized variables). -W. */ + +extern int extra_warnings; + +/* Nonzero to warn about unused local variables. */ + +extern int warn_unused; + +/* Nonzero means warn if inline function is too large. */ + +extern int warn_inline; + +/* Nonzero to warn about variables used before they are initialized. */ + +extern int warn_uninitialized; + +/* Nonzero means warn about all declarations which shadow others. */ + +extern int warn_shadow; + +/* Warn if a switch on an enum fails to have a case for every enum value. */ + +extern int warn_switch; + +/* Nonzero means warn about function definitions that default the return type + or that use a null return and have a return-type other than void. */ + +extern int warn_return_type; + +/* Nonzero means warn about pointer casts that increase the required + alignment of the target type (and might therefore lead to a crash + due to a misaligned access). */ + +extern int warn_cast_align; + +/* Nonzero means warn that dbx info for template class methods isn't fully + supported yet. */ + +extern int warn_template_debugging; + +/* Nonzero means warn about any identifiers that match in the first N + characters. The value N is in `id_clash_len'. */ + +extern int warn_id_clash; +extern unsigned id_clash_len; + +/* Nonzero means warn about any objects definitions whose size is larger + than N bytes. Also want about function definitions whose returned + values are larger than N bytes. The value N is in `larger_than_size'. */ + +extern int warn_larger_than; +extern unsigned larger_than_size; + +/* Warn if a function returns an aggregate, + since there are often incompatible calling conventions for doing this. */ + +extern int warn_aggregate_return; + +/* Nonzero if generating code to do profiling. */ + +extern int profile_flag; + +/* Nonzero if generating code to do profiling on the basis of basic blocks. */ + +extern int profile_block_flag; + +/* Nonzero for -pedantic switch: warn about anything + that standard C forbids. */ + +extern int pedantic; + +/* Temporarily suppress certain warnings. + This is set while reading code from a system header file. */ + +extern int in_system_header; + +/* Nonzero for -dp: annotate the assembly with a comment describing the + pattern and alternative used. */ + +extern int flag_print_asm_name; + +/* Now the symbols that are set with `-f' switches. */ + +/* Nonzero means `char' should be signed. */ + +extern int flag_signed_char; + +/* Nonzero means give an enum type only as many bytes as it needs. */ + +extern int flag_short_enums; + +/* Nonzero for -fcaller-saves: allocate values in regs that need to + be saved across function calls, if that produces overall better code. + Optional now, so people can test it. */ + +extern int flag_caller_saves; + +/* Nonzero for -fpcc-struct-return: return values the same way PCC does. */ + +extern int flag_pcc_struct_return; + +/* Nonzero for -fforce-mem: load memory value into a register + before arithmetic on it. This makes better cse but slower compilation. */ + +extern int flag_force_mem; + +/* Nonzero for -fforce-addr: load memory address into a register before + reference to memory. This makes better cse but slower compilation. */ + +extern int flag_force_addr; + +/* Nonzero for -fdefer-pop: don't pop args after each function call; + instead save them up to pop many calls' args with one insns. */ + +extern int flag_defer_pop; + +/* Nonzero for -ffloat-store: don't allocate floats and doubles + in extended-precision registers. */ + +extern int flag_float_store; + +/* Nonzero enables strength-reduction in loop.c. */ + +extern int flag_strength_reduce; + +/* Nonzero enables loop unrolling in unroll.c. Only loops for which the + number of iterations can be calculated at compile-time (UNROLL_COMPLETELY, + UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are + unrolled. */ + +extern int flag_unroll_loops; + +/* Nonzero enables loop unrolling in unroll.c. All loops are unrolled. + This is generally not a win. */ + +extern int flag_unroll_all_loops; + +/* Nonzero for -fcse-follow-jumps: + have cse follow jumps to do a more extensive job. */ + +extern int flag_cse_follow_jumps; + +/* Nonzero for -fcse-skip-blocks: + have cse follow a branch around a block. */ + +extern int flag_cse_skip_blocks; + +/* Nonzero for -fexpensive-optimizations: + perform miscellaneous relatively-expensive optimizations. */ +extern int flag_expensive_optimizations; + +/* Nonzero for -fwritable-strings: + store string constants in data segment and don't uniquize them. */ + +extern int flag_writable_strings; + +/* Nonzero means don't put addresses of constant functions in registers. + Used for compiling the Unix kernel, where strange substitutions are + done on the assembly output. */ + +extern int flag_no_function_cse; + +/* Nonzero for -fomit-frame-pointer: + don't make a frame pointer in simple functions that don't require one. */ + +extern int flag_omit_frame_pointer; + +/* Nonzero to inhibit use of define_optimization peephole opts. */ + +extern int flag_no_peephole; + +/* Nonzero means all references through pointers are volatile. */ + +extern int flag_volatile; + +/* Nonzero means treat all global and extern variables as global. */ + +extern int flag_volatile_global; + +/* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math + operations in the interest of optimization. For example it allows + GCC to assume arguments to sqrt are nonnegative numbers, allowing + faster code for sqrt to be generated. */ + +extern int flag_fast_math; + +/* Nonzero means make functions that look like good inline candidates + go inline. */ + +extern int flag_inline_functions; + +/* Nonzero for -fkeep-inline-functions: even if we make a function + go inline everywhere, keep its definition around for debugging + purposes. */ + +extern int flag_keep_inline_functions; + +/* Nonzero means that functions declared `inline' will be treated + as `static'. Prevents generation of zillions of copies of unused + static inline functions; instead, `inlines' are written out + only when actually used. Used in conjunction with -g. Also + does the right thing with #pragma interface. */ + +extern int flag_no_inline; + +/* Nonzero if we are only using compiler to check syntax errors. */ + +extern int flag_syntax_only; + +/* Nonzero means we should save auxiliary info into a .X file. */ + +extern int flag_gen_aux_info; + +/* Nonzero means make the text shared if supported. */ + +extern int flag_shared_data; + +/* flag_schedule_insns means schedule insns within basic blocks (before + local_alloc). + flag_schedule_insns_after_reload means schedule insns after + global_alloc. */ + +extern int flag_schedule_insns; +extern int flag_schedule_insns_after_reload; + +/* Nonzero means put things in delayed-branch slots if supported. */ + +extern int flag_delayed_branch; + +/* Nonzero means to run cleanups after CALL_EXPRs. */ + +extern int flag_short_temps; + +/* Nonzero means pretend it is OK to examine bits of target floats, + even if that isn't true. The resulting code will have incorrect constants, + but the same series of instructions that the native compiler would make. */ + +extern int flag_pretend_float; + +/* Nonzero means change certain warnings into errors. + Usually these are warnings about failure to conform to some standard. */ + +extern int flag_pedantic_errors; + +/* Nonzero means generate position-independent code. + This is not fully implemented yet. */ + +extern int flag_pic; + +/* Nonzero means place uninitialized global data in the bss section. */ + +extern int flag_no_common; + +/* -finhibit-size-directive inhibits output of .size for ELF. + This is used only for compiling crtstuff.c, + and it may be extended to other effects + needed for crtstuff.c on other systems. */ +extern int flag_inhibit_size_directive; + +/* -fverbose-asm causes extra commentary information to be produced in + the generated assembly code (to make it more readable). This option + is generally only of use to those who actually need to read the + generated assembly code (perhaps while debugging the compiler itself). */ + +extern int flag_verbose_asm; + +/* -fgnu-linker specifies use of the GNU linker for initializations. + -fno-gnu-linker says that collect will be used. */ +extern int flag_gnu_linker; + +/* Other basic status info about current function. */ + +/* Nonzero means current function must be given a frame pointer. + Set in stmt.c if anything is allocated on the stack there. + Set in reload1.c if anything is allocated on the stack there. */ + +extern int frame_pointer_needed; + +/* Set nonzero if jump_optimize finds that control falls through + at the end of the function. */ + +extern int can_reach_end; + +/* Nonzero if function being compiled receives nonlocal gotos + from nested functions. */ + +extern int current_function_has_nonlocal_label; + +/* Nonzero if function being compiled has nonlocal gotos to parent + function. */ + +extern int current_function_has_nonlocal_goto; diff --git a/gnu/usr.bin/cc/include/function.h b/gnu/usr.bin/cc/include/function.h new file mode 100644 index 0000000..b37a59a --- /dev/null +++ b/gnu/usr.bin/cc/include/function.h @@ -0,0 +1,216 @@ +/* Structure for saving state for a nested function. + Copyright (C) 1989, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +#ifndef NULL_TREE +#define tree int * +#endif +#ifndef GET_CODE +#define rtx int * +#endif + +struct var_refs_queue + { + rtx modified; + enum machine_mode promoted_mode; + int unsignedp; + struct var_refs_queue *next; + }; + +/* Stack of pending (incomplete) sequences saved by `start_sequence'. + Each element describes one pending sequence. + The main insn-chain is saved in the last element of the chain, + unless the chain is empty. */ + +struct sequence_stack +{ + /* First and last insns in the chain of the saved sequence. */ + rtx first, last; + tree sequence_rtl_expr; + struct sequence_stack *next; +}; + +extern struct sequence_stack *sequence_stack; + +/* This structure can save all the important global and static variables + describing the status of the current function. */ + +struct function +{ + struct function *next; + + /* For function.c. */ + char *name; + tree decl; + int pops_args; + int returns_struct; + int returns_pcc_struct; + int needs_context; + int calls_setjmp; + int calls_longjmp; + int calls_alloca; + int has_nonlocal_label; + int has_nonlocal_goto; + rtx nonlocal_goto_handler_slot; + rtx nonlocal_goto_stack_level; + tree nonlocal_labels; + int args_size; + int pretend_args_size; + rtx arg_offset_rtx; + int varargs; + int max_parm_reg; + rtx *parm_reg_stack_loc; + int outgoing_args_size; + rtx return_rtx; + rtx cleanup_label; + rtx return_label; + rtx save_expr_regs; + rtx stack_slot_list; + rtx parm_birth_insn; + int frame_offset; + rtx tail_recursion_label; + rtx tail_recursion_reentry; + rtx internal_arg_pointer; + rtx arg_pointer_save_area; + tree rtl_expr_chain; + rtx last_parm_insn; + tree context_display; + tree trampoline_list; + int function_call_count; + struct temp_slot *temp_slots; + int temp_slot_level; + /* This slot is initialized as 0 and is added to + during the nested function. */ + struct var_refs_queue *fixup_var_refs_queue; + + /* For stmt.c */ + struct nesting *block_stack; + struct nesting *stack_block_stack; + struct nesting *cond_stack; + struct nesting *loop_stack; + struct nesting *case_stack; + struct nesting *nesting_stack; + int nesting_depth; + int block_start_count; + tree last_expr_type; + rtx last_expr_value; + int expr_stmts_for_value; + char *emit_filename; + int emit_lineno; + struct goto_fixup *goto_fixup_chain; + + /* For expr.c. */ + int pending_stack_adjust; + int inhibit_defer_pop; + tree cleanups_this_call; + rtx saveregs_value; + rtx apply_args_value; + rtx forced_labels; + + /* For emit-rtl.c. */ + int reg_rtx_no; + int first_label_num; + rtx first_insn; + rtx last_insn; + tree sequence_rtl_expr; + struct sequence_stack *sequence_stack; + int cur_insn_uid; + int last_linenum; + char *last_filename; + char *regno_pointer_flag; + int regno_pointer_flag_length; + rtx *regno_reg_rtx; + + /* For stor-layout.c. */ + tree permanent_type_chain; + tree temporary_type_chain; + tree permanent_type_end; + tree temporary_type_end; + tree pending_sizes; + int immediate_size_expand; + + /* For tree.c. */ + int all_types_permanent; + struct momentary_level *momentary_stack; + char *maybepermanent_firstobj; + char *temporary_firstobj; + char *momentary_firstobj; + char *momentary_function_firstobj; + struct obstack *current_obstack; + struct obstack *function_obstack; + struct obstack *function_maybepermanent_obstack; + struct obstack *expression_obstack; + struct obstack *saveable_obstack; + struct obstack *rtl_obstack; + + /* For integrate.c. */ + int uses_const_pool; + + /* For md files. */ + int uses_pic_offset_table; + /* tm.h can use this to store whatever it likes. */ + struct machine_function *machine; + + /* For reorg. */ + rtx epilogue_delay_list; + + /* For varasm. */ + struct constant_descriptor **const_rtx_hash_table; + struct pool_sym **const_rtx_sym_hash_table; + struct pool_constant *first_pool, *last_pool; + int pool_offset; +}; + +/* The FUNCTION_DECL for an inline function currently being expanded. */ +extern tree inline_function_decl; + +/* Label that will go on function epilogue. + Jumping to this label serves as a "return" instruction + on machines which require execution of the epilogue on all returns. */ +extern rtx return_label; + +/* List (chain of EXPR_LISTs) of all stack slots in this function. + Made for the sake of unshare_all_rtl. */ +extern rtx stack_slot_list; + +/* Given a function decl for a containing function, + return the `struct function' for it. */ +struct function *find_function_data PROTO((tree)); + +/* Pointer to chain of `struct function' for containing functions. */ +extern struct function *outer_function_chain; + +/* Put all this function's BLOCK nodes into a vector and return it. + Also store in each NOTE for the beginning or end of a block + the index of that block in the vector. */ +extern tree *identify_blocks PROTO((tree, rtx)); + +/* These variables hold pointers to functions to + save and restore machine-specific data, + in push_function_context and pop_function_context. */ +extern void (*save_machine_status) (); +extern void (*restore_machine_status) (); + +#ifdef rtx +#undef rtx +#endif + +#ifdef tree +#undef tree +#endif diff --git a/gnu/usr.bin/cc/include/gbl-ctors.h b/gnu/usr.bin/cc/include/gbl-ctors.h new file mode 100644 index 0000000..2e7f520 --- /dev/null +++ b/gnu/usr.bin/cc/include/gbl-ctors.h @@ -0,0 +1,80 @@ +/* Definitions relating to the special __do_global_init function used + for getting g++ file-scope static objects constructed. This file + will get included either by libgcc2.c (for systems that don't support + a .init section) or by crtstuff.c (for those that do). + + Written by Ron Guilmette (rfg@netcom.com) + +Copyright (C) 1991 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This file contains definitions and declarations of things + relating to the normal start-up-time invocation of C++ + file-scope static object constructors. These declarations + and definitions are used by *both* libgcc2.c and by crtstuff.c. + + Note that this file should only be compiled with GCC. +*/ + +#ifdef HAVE_ATEXIT +extern void atexit (void (*) (void)); +#define ON_EXIT(FUNC,ARG) atexit ((FUNC)) +#else +#ifdef sun +extern void on_exit (void*, void*); +#define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG)) +#endif +#endif + +/* Declare a pointer to void function type. */ + +typedef void (*func_ptr) (void); + +/* Declare the set of symbols use as begin and end markers for the lists + of global object constructors and global object destructors. */ + +extern func_ptr __CTOR_LIST__[]; +extern func_ptr __DTOR_LIST__[]; + +/* Declare the routine which need to get invoked at program exit time. */ + +extern void __do_global_dtors (); + +/* Define a macro with the code which needs to be executed at program + start-up time. This macro is used in two places in crtstuff.c (for + systems which support a .init section) and in one place in libgcc2.c + (for those system which do *not* support a .init section). For all + three places where this code might appear, it must be identical, so + we define it once here as a macro to avoid various instances getting + out-of-sync with one another. */ + +/* The first word may or may not contain the number of pointers in the table. + In all cases, the table is null-terminated. + We ignore the first word and scan up to the null. */ + +/* Some systems use a different strategy for finding the ctors. + For example, svr3. */ +#ifndef DO_GLOBAL_CTORS_BODY +#define DO_GLOBAL_CTORS_BODY \ +do { \ + func_ptr *p; \ + for (p = __CTOR_LIST__ + 1; *p; ) \ + (*p++) (); \ +} while (0) +#endif + diff --git a/gnu/usr.bin/cc/include/glimits.h b/gnu/usr.bin/cc/include/glimits.h new file mode 100644 index 0000000..ff25a97 --- /dev/null +++ b/gnu/usr.bin/cc/include/glimits.h @@ -0,0 +1,93 @@ +#ifndef _LIMITS_H___ +#ifndef _MACH_MACHLIMITS_H_ + +/* _MACH_MACHLIMITS_H_ is used on OSF/1. */ +#define _LIMITS_H___ +#define _MACH_MACHLIMITS_H_ + +/* Number of bits in a `char'. */ +#undef CHAR_BIT +#define CHAR_BIT 8 + +/* Maximum length of a multibyte character. */ +#ifndef MB_LEN_MAX +#define MB_LEN_MAX 1 +#endif + +/* Minimum and maximum values a `signed char' can hold. */ +#undef SCHAR_MIN +#define SCHAR_MIN (-128) +#undef SCHAR_MAX +#define SCHAR_MAX 127 + +/* Maximum value an `unsigned char' can hold. (Minimum is 0). */ +#undef UCHAR_MAX +#define UCHAR_MAX 255 + +/* Minimum and maximum values a `char' can hold. */ +#ifdef __CHAR_UNSIGNED__ +#undef CHAR_MIN +#define CHAR_MIN 0 +#undef CHAR_MAX +#define CHAR_MAX 255 +#else +#undef CHAR_MIN +#define CHAR_MIN (-128) +#undef CHAR_MAX +#define CHAR_MAX 127 +#endif + +/* Minimum and maximum values a `signed short int' can hold. */ +#undef SHRT_MIN +#define SHRT_MIN (-32768) +#undef SHRT_MAX +#define SHRT_MAX 32767 + +/* Maximum value an `unsigned short int' can hold. (Minimum is 0). */ +#undef USHRT_MAX +#define USHRT_MAX 65535 + +/* Minimum and maximum values a `signed int' can hold. */ +#ifndef __INT_MAX__ +#define __INT_MAX__ 2147483647 +#endif +#undef INT_MIN +#define INT_MIN (-INT_MAX-1) +#undef INT_MAX +#define INT_MAX __INT_MAX__ + +/* Maximum value an `unsigned int' can hold. (Minimum is 0). */ +#undef UINT_MAX +#define UINT_MAX (INT_MAX * 2U + 1) + +/* Minimum and maximum values a `signed long int' can hold. + (Same as `int'). */ +#ifndef __LONG_MAX__ +#define __LONG_MAX__ 2147483647L +#endif +#undef LONG_MIN +#define LONG_MIN (-LONG_MAX-1) +#undef LONG_MAX +#define LONG_MAX __LONG_MAX__ + +/* Maximum value an `unsigned long int' can hold. (Minimum is 0). */ +#undef ULONG_MAX +#define ULONG_MAX (LONG_MAX * 2UL + 1) + +#if defined (__GNU_LIBRARY__) ? defined (__USE_GNU) : !defined (__STRICT_ANSI__) +/* Minimum and maximum values a `signed long long int' can hold. */ +#ifndef __LONG_LONG_MAX__ +#define __LONG_LONG_MAX__ 9223372036854775807LL +#endif +#undef LONG_LONG_MIN +#define LONG_LONG_MIN (-LONG_LONG_MAX-1) +#undef LONG_LONG_MAX +#define LONG_LONG_MAX __LONG_LONG_MAX__ + +/* Maximum value an `unsigned long long int' can hold. (Minimum is 0). */ +#undef ULONG_LONG_MAX +#define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1) +#endif + +#endif /* _MACH_MACHLIMITS_H_ */ +#endif /* _LIMITS_H___ */ diff --git a/gnu/usr.bin/cc/include/hard-reg-set.h b/gnu/usr.bin/cc/include/hard-reg-set.h new file mode 100644 index 0000000..6bc668b --- /dev/null +++ b/gnu/usr.bin/cc/include/hard-reg-set.h @@ -0,0 +1,270 @@ +/* Sets (bit vectors) of hard registers, and operations on them. + Copyright (C) 1987, 1992, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* Define the type of a set of hard registers. */ + +/* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which + will be used for hard reg sets, either alone or in an array. + + If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE, + and it has enough bits to represent all the target machine's hard + registers. Otherwise, it is a typedef for a suitably sized array + of HARD_REG_ELT_TYPEs. HARD_REG_SET_LONGS is defined as how many. + + Note that lots of code assumes that the first part of a regset is + the same format as a HARD_REG_SET. To help make sure this is true, + we only try the widest integer mode (HOST_WIDE_INT) instead of all the + smaller types. This approach loses only if there are a very few + registers and then only in the few cases where we have an array of + HARD_REG_SETs, so it needn't be as complex as it used to be. */ + +typedef unsigned HOST_WIDE_INT HARD_REG_ELT_TYPE; + +#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDE_INT + +#define HARD_REG_SET HARD_REG_ELT_TYPE + +#else + +#define HARD_REG_SET_LONGS \ + ((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDE_INT - 1) \ + / HOST_BITS_PER_WIDE_INT) +typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS]; + +#endif + +/* HARD_CONST is used to cast a constant to the appropriate type + for use with a HARD_REG_SET. */ + +#define HARD_CONST(X) ((HARD_REG_ELT_TYPE) (X)) + +/* Define macros SET_HARD_REG_BIT, CLEAR_HARD_REG_BIT and TEST_HARD_REG_BIT + to set, clear or test one bit in a hard reg set of type HARD_REG_SET. + All three take two arguments: the set and the register number. + + In the case where sets are arrays of longs, the first argument + is actually a pointer to a long. + + Define two macros for initializing a set: + CLEAR_HARD_REG_SET and SET_HARD_REG_SET. + These take just one argument. + + Also define macros for copying hard reg sets: + COPY_HARD_REG_SET and COMPL_HARD_REG_SET. + These take two arguments TO and FROM; they read from FROM + and store into TO. COMPL_HARD_REG_SET complements each bit. + + Also define macros for combining hard reg sets: + IOR_HARD_REG_SET and AND_HARD_REG_SET. + These take two arguments TO and FROM; they read from FROM + and combine bitwise into TO. Define also two variants + IOR_COMPL_HARD_REG_SET and AND_COMPL_HARD_REG_SET + which use the complement of the set FROM. + + Also define GO_IF_HARD_REG_SUBSET (X, Y, TO): + if X is a subset of Y, go to TO. +*/ + +#ifdef HARD_REG_SET + +#define SET_HARD_REG_BIT(SET, BIT) \ + ((SET) |= HARD_CONST (1) << (BIT)) +#define CLEAR_HARD_REG_BIT(SET, BIT) \ + ((SET) &= ~(HARD_CONST (1) << (BIT))) +#define TEST_HARD_REG_BIT(SET, BIT) \ + ((SET) & (HARD_CONST (1) << (BIT))) + +#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0)) +#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0)) + +#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM)) +#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM)) + +#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM)) +#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM)) +#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM)) +#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM)) + +#define GO_IF_HARD_REG_SUBSET(X,Y,TO) if (HARD_CONST (0) == ((X) & ~(Y))) goto TO + +#define GO_IF_HARD_REG_EQUAL(X,Y,TO) if ((X) == (Y)) goto TO + +#else + +#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDE_INT) + +#define SET_HARD_REG_BIT(SET, BIT) \ + ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ + |= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)) + +#define CLEAR_HARD_REG_BIT(SET, BIT) \ + ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ + &= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))) + +#define TEST_HARD_REG_BIT(SET, BIT) \ + ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT] \ + & (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))) + +#define CLEAR_HARD_REG_SET(TO) \ +do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ + register int i; \ + for (i = 0; i < HARD_REG_SET_LONGS; i++) \ + *scan_tp_++ = 0; } while (0) + +#define SET_HARD_REG_SET(TO) \ +do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO); \ + register int i; \ + for (i = 0; i < HARD_REG_SET_LONGS; i++) \ + *scan_tp_++ = -1; } while (0) + +#define COPY_HARD_REG_SET(TO, FROM) \ +do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ + register int i; \ + for (i = 0; i < HARD_REG_SET_LONGS; i++) \ + *scan_tp_++ = *scan_fp_++; } while (0) + +#define COMPL_HARD_REG_SET(TO, FROM) \ +do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ + register int i; \ + for (i = 0; i < HARD_REG_SET_LONGS; i++) \ + *scan_tp_++ = ~ *scan_fp_++; } while (0) + +#define AND_HARD_REG_SET(TO, FROM) \ +do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ + register int i; \ + for (i = 0; i < HARD_REG_SET_LONGS; i++) \ + *scan_tp_++ &= *scan_fp_++; } while (0) + +#define AND_COMPL_HARD_REG_SET(TO, FROM) \ +do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ + register int i; \ + for (i = 0; i < HARD_REG_SET_LONGS; i++) \ + *scan_tp_++ &= ~ *scan_fp_++; } while (0) + +#define IOR_HARD_REG_SET(TO, FROM) \ +do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ + register int i; \ + for (i = 0; i < HARD_REG_SET_LONGS; i++) \ + *scan_tp_++ |= *scan_fp_++; } while (0) + +#define IOR_COMPL_HARD_REG_SET(TO, FROM) \ +do { register HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); \ + register int i; \ + for (i = 0; i < HARD_REG_SET_LONGS; i++) \ + *scan_tp_++ |= ~ *scan_fp_++; } while (0) + +#define GO_IF_HARD_REG_SUBSET(X,Y,TO) \ +do { register HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ + register int i; \ + for (i = 0; i < HARD_REG_SET_LONGS; i++) \ + if (0 != (*scan_xp_++ & ~ *scan_yp_++)) break; \ + if (i == HARD_REG_SET_LONGS) goto TO; } while (0) + +#define GO_IF_HARD_REG_EQUAL(X,Y,TO) \ +do { register HARD_REG_ELT_TYPE *scan_xp_ = (X), *scan_yp_ = (Y); \ + register int i; \ + for (i = 0; i < HARD_REG_SET_LONGS; i++) \ + if (*scan_xp_++ != *scan_yp_++) break; \ + if (i == HARD_REG_SET_LONGS) goto TO; } while (0) + +#endif + +/* Define some standard sets of registers. */ + +/* Indexed by hard register number, contains 1 for registers + that are fixed use (stack pointer, pc, frame pointer, etc.). + These are the registers that cannot be used to allocate + a pseudo reg whose life does not cross calls. */ + +extern char fixed_regs[FIRST_PSEUDO_REGISTER]; + +/* The same info as a HARD_REG_SET. */ + +extern HARD_REG_SET fixed_reg_set; + +/* Indexed by hard register number, contains 1 for registers + that are fixed use or are clobbered by function calls. + These are the registers that cannot be used to allocate + a pseudo reg whose life crosses calls. */ + +extern char call_used_regs[FIRST_PSEUDO_REGISTER]; + +/* The same info as a HARD_REG_SET. */ + +extern HARD_REG_SET call_used_reg_set; + +/* Indexed by hard register number, contains 1 for registers that are + fixed use -- i.e. in fixed_regs -- or a function value return register + or STRUCT_VALUE_REGNUM or STATIC_CHAIN_REGNUM. These are the + registers that cannot hold quantities across calls even if we are + willing to save and restore them. */ + +extern char call_fixed_regs[FIRST_PSEUDO_REGISTER]; + +/* The same info as a HARD_REG_SET. */ + +extern HARD_REG_SET call_fixed_reg_set; + +/* Indexed by hard register number, contains 1 for registers + that are being used for global register decls. + These must be exempt from ordinary flow analysis + and are also considered fixed. */ + +extern char global_regs[FIRST_PSEUDO_REGISTER]; + +/* Table of register numbers in the order in which to try to use them. */ + +#ifdef REG_ALLOC_ORDER /* Avoid undef symbol in certain broken linkers. */ +extern int reg_alloc_order[FIRST_PSEUDO_REGISTER]; +#endif + +/* For each reg class, a HARD_REG_SET saying which registers are in it. */ + +extern HARD_REG_SET reg_class_contents[]; + +/* For each reg class, number of regs it contains. */ + +extern int reg_class_size[N_REG_CLASSES]; + +/* For each reg class, table listing all the containing classes. */ + +extern enum reg_class reg_class_superclasses[N_REG_CLASSES][N_REG_CLASSES]; + +/* For each reg class, table listing all the classes contained in it. */ + +extern enum reg_class reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES]; + +/* For each pair of reg classes, + a largest reg class contained in their union. */ + +extern enum reg_class reg_class_subunion[N_REG_CLASSES][N_REG_CLASSES]; + +/* For each pair of reg classes, + the smallest reg class that contains their union. */ + +extern enum reg_class reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES]; + +/* Number of non-fixed registers. */ + +extern int n_non_fixed_regs; + +/* Vector indexed by hardware reg giving its name. */ + +extern char *reg_names[FIRST_PSEUDO_REGISTER]; diff --git a/gnu/usr.bin/cc/include/i386/bsd.h b/gnu/usr.bin/cc/include/i386/bsd.h new file mode 100644 index 0000000..8aec304 --- /dev/null +++ b/gnu/usr.bin/cc/include/i386/bsd.h @@ -0,0 +1,129 @@ +/* Definitions for BSD assembler syntax for Intel 386 + (actually AT&T syntax for insns and operands, + adapted to BSD conventions for symbol names and debugging.) + Copyright (C) 1988 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Include common aspects of all 386 Unix assemblers. */ +#include "i386/unix.h" + +/* Use the Sequent Symmetry assembler syntax. */ + +#define TARGET_VERSION fprintf (stderr, " (80386, BSD syntax)"); + +/* Define the syntax of pseudo-ops, labels and comments. */ + +/* Prefix for internally generated assembler labels. If we aren't using + underscores, we are using prefix `.'s to identify labels that should + be ignored, as in `i386/gas.h' --karl@cs.umb.edu */ +#ifdef NO_UNDERSCORES +#define LPREFIX ".L" +#else +#define LPREFIX "L" +#endif /* not NO_UNDERSCORES */ + +/* Assembler pseudos to introduce constants of various size. */ + +#define ASM_BYTE_OP "\t.byte" +#define ASM_SHORT "\t.word" +#define ASM_LONG "\t.long" +#define ASM_DOUBLE "\t.double" + +/* Output at beginning of assembler file. + ??? I am skeptical of this -- RMS. */ + +#define ASM_FILE_START(FILE) \ + do { fprintf (FILE, "\t.file\t"); \ + output_quoted_string (FILE, dump_base_name); \ + fprintf (FILE, "\n"); \ + } while (0) + +/* This was suggested, but it shouldn't be right for DBX output. -- RMS + #define ASM_OUTPUT_SOURCE_FILENAME(FILE, NAME) */ + + +/* Define the syntax of labels and symbol definitions/declarations. */ + +/* This is how to output an assembler line + that says to advance the location counter by SIZE bytes. */ + +#define ASM_OUTPUT_SKIP(FILE,SIZE) \ + fprintf (FILE, "\t.space %u\n", (SIZE)) + +/* Define the syntax of labels and symbol definitions/declarations. */ + +/* This says how to output an assembler line + to define a global common symbol. */ + +#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ +( fputs (".comm ", (FILE)), \ + assemble_name ((FILE), (NAME)), \ + fprintf ((FILE), ",%u\n", (ROUNDED))) + +/* This says how to output an assembler line + to define a local common symbol. */ + +#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ +( fputs (".lcomm ", (FILE)), \ + assemble_name ((FILE), (NAME)), \ + fprintf ((FILE), ",%u\n", (ROUNDED))) + +/* 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)) + +/* This is how to store into the string BUF + the symbol_ref name of an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. + This is suitable for output with `assemble_name'. */ + +#ifdef NO_UNDERSCORES +#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ + sprintf ((BUF), "*.%s%d", (PREFIX), (NUMBER)) +#else +#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ + sprintf ((BUF), "*%s%d", (PREFIX), (NUMBER)) +#endif + +/* This is how to output an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. */ + +#ifdef NO_UNDERSCORES +#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ + fprintf (FILE, ".%s%d:\n", PREFIX, NUM) +#else +#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ + fprintf (FILE, "%s%d:\n", PREFIX, NUM) +#endif + +/* This is how to output a reference to a user-level label named NAME. */ + +#ifdef NO_UNDERSCORES +#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "%s", NAME) +#else +#define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "_%s", NAME) +#endif /* not NO_UNDERSCORES */ + +/* Sequent has some changes in the format of DBX symbols. */ +#define DBX_NO_XREFS 1 + +/* Don't split DBX symbols into continuations. */ +#define DBX_CONTIN_LENGTH 0 diff --git a/gnu/usr.bin/cc/include/i386/gas.h b/gnu/usr.bin/cc/include/i386/gas.h new file mode 100644 index 0000000..3e8dba5 --- /dev/null +++ b/gnu/usr.bin/cc/include/i386/gas.h @@ -0,0 +1,154 @@ +/* Definitions for Intel 386 running system V with gnu tools + Copyright (C) 1988, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Note that i386/seq-gas.h is a GAS configuration that does not use this + file. */ + +#include "i386/i386.h" + +#ifndef YES_UNDERSCORES +/* Define this now, because i386/bsd.h tests it. */ +#define NO_UNDERSCORES +#endif + +/* Use the bsd assembler syntax. */ +/* we need to do this because gas is really a bsd style assembler, + * and so doesn't work well this these att-isms: + * + * ASM_OUTPUT_SKIP is .set .,.+N, which isn't implemented in gas + * ASM_OUTPUT_LOCAL is done with .set .,.+N, but that can't be + * used to define bss static space + * + * Next is the question of whether to uses underscores. RMS didn't + * like this idea at first, but since it is now obvious that we + * need this separate tm file for use with gas, at least to get + * dbx debugging info, I think we should also switch to underscores. + * We can keep i386v for real att style output, and the few + * people who want both form will have to compile twice. + */ + +#include "i386/bsd.h" + +/* these come from i386/bsd.h, but are specific to sequent */ +#undef DBX_NO_XREFS +#undef DBX_CONTIN_LENGTH + +/* Ask for COFF symbols. */ + +#define SDB_DEBUGGING_INFO + +/* Specify predefined symbols in preprocessor. */ + +#define CPP_PREDEFINES "-Dunix -Di386 -Asystem(unix) -Acpu(i386) -Amachine(i386)" +#define CPP_SPEC "%{posix:-D_POSIX_SOURCE}" + +/* Allow #sccs in preprocessor. */ + +#define SCCS_DIRECTIVE + +/* Output #ident as a .ident. */ + +#define ASM_OUTPUT_IDENT(FILE, NAME) fprintf (FILE, "\t.ident \"%s\"\n", NAME); + +/* Implicit library calls should use memcpy, not bcopy, etc. */ + +#define TARGET_MEM_FUNCTIONS + +#if 0 /* People say gas uses the log as the arg to .align. */ +/* When using gas, .align N aligns to an N-byte boundary. */ + +#undef ASM_OUTPUT_ALIGN +#define ASM_OUTPUT_ALIGN(FILE,LOG) \ + if ((LOG)!=0) fprintf ((FILE), "\t.align %d\n", 1<<(LOG)) +#endif + +/* Align labels, etc. at 4-byte boundaries. + For the 486, align to 16-byte boundary for sake of cache. */ + +#undef ASM_OUTPUT_ALIGN_CODE +#define ASM_OUTPUT_ALIGN_CODE(FILE) \ + fprintf ((FILE), "\t.align %d,0x90\n", \ + TARGET_486 ? 4 : 2); /* Use log of 16 or log of 4 as arg. */ + +/* Align start of loop at 4-byte boundary. */ + +#undef ASM_OUTPUT_LOOP_ALIGN +#define ASM_OUTPUT_LOOP_ALIGN(FILE) \ + fprintf ((FILE), "\t.align 2,0x90\n"); /* Use log of 4 as arg. */ + +/* A C statement or statements which output an assembler instruction + opcode to the stdio stream STREAM. The macro-operand PTR is a + variable of type `char *' which points to the opcode name in its + "internal" form--the form that is written in the machine description. + + GAS version 1.38.1 doesn't understand the `repz' opcode mnemonic. + So use `repe' instead. */ + +#define ASM_OUTPUT_OPCODE(STREAM, PTR) \ +{ \ + if ((PTR)[0] == 'r' \ + && (PTR)[1] == 'e' \ + && (PTR)[2] == 'p') \ + { \ + if ((PTR)[3] == 'z') \ + { \ + fprintf (STREAM, "repe"); \ + (PTR) += 4; \ + } \ + else if ((PTR)[3] == 'n' && (PTR)[4] == 'z') \ + { \ + fprintf (STREAM, "repne"); \ + (PTR) += 5; \ + } \ + } \ +} + +/* Define macro used to output shift-double opcodes when the shift + count is in %cl. Some assemblers require %cl as an argument; + some don't. + + GAS requires the %cl argument, so override i386/unix.h. */ + +#undef AS3_SHIFT_DOUBLE +#define AS3_SHIFT_DOUBLE(a,b,c,d) AS3 (a,b,c,d) + +/* Print opcodes the way that GAS expects them. */ +#define GAS_MNEMONICS 1 + +#ifdef NO_UNDERSCORES /* If user-symbols don't have underscores, + then it must take more than `L' to identify + a label that should be ignored. */ + +/* This is how to store into the string BUF + the symbol_ref name of an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. + This is suitable for output with `assemble_name'. */ + +#undef ASM_GENERATE_INTERNAL_LABEL +#define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ + sprintf ((BUF), ".%s%d", (PREFIX), (NUMBER)) + +/* This is how to output an internal numbered label where + PREFIX is the class of label and NUM is the number within the class. */ + +#undef ASM_OUTPUT_INTERNAL_LABEL +#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ + fprintf (FILE, ".%s%d:\n", PREFIX, NUM) + +#endif /* NO_UNDERSCORES */ diff --git a/gnu/usr.bin/cc/include/i386/gstabs.h b/gnu/usr.bin/cc/include/i386/gstabs.h new file mode 100644 index 0000000..5f0ae34 --- /dev/null +++ b/gnu/usr.bin/cc/include/i386/gstabs.h @@ -0,0 +1,9 @@ +#include "i386/gas.h" + +/* We do not want to output SDB debugging information. */ + +#undef SDB_DEBUGGING_INFO + +/* We want to output DBX debugging information. */ + +#define DBX_DEBUGGING_INFO diff --git a/gnu/usr.bin/cc/include/i386/i386.h b/gnu/usr.bin/cc/include/i386/i386.h new file mode 100644 index 0000000..983bfc5 --- /dev/null +++ b/gnu/usr.bin/cc/include/i386/i386.h @@ -0,0 +1,1665 @@ +/* Definitions of target machine for GNU compiler for Intel 80386. + Copyright (C) 1988, 1992, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* The purpose of this file is to define the characteristics of the i386, + independent of assembler syntax or operating system. + + Three other files build on this one to describe a specific assembler syntax: + bsd386.h, att386.h, and sun386.h. + + The actual tm.h file for a particular system should include + this file, and then the file for the appropriate assembler syntax. + + Many macros that specify assembler syntax are omitted entirely from + this file because they really belong in the files for particular + assemblers. These include AS1, AS2, AS3, RP, IP, LPREFIX, L_SIZE, + PUT_OP_SIZE, USE_STAR, ADDR_BEG, ADDR_END, PRINT_IREG, PRINT_SCALE, + PRINT_B_I_S, and many that start with ASM_ or end in ASM_OP. */ + +/* Names to predefine in the preprocessor for this target machine. */ + +#define I386 1 + +/* Stubs for half-pic support if not OSF/1 reference platform. */ + +#ifndef HALF_PIC_P +#define HALF_PIC_P() 0 +#define HALF_PIC_NUMBER_PTRS 0 +#define HALF_PIC_NUMBER_REFS 0 +#define HALF_PIC_ENCODE(DECL) +#define HALF_PIC_DECLARE(NAME) +#define HALF_PIC_INIT() error ("half-pic init called on systems that don't support it.") +#define HALF_PIC_ADDRESS_P(X) 0 +#define HALF_PIC_PTR(X) X +#define HALF_PIC_FINISH(STREAM) +#endif + +/* Run-time compilation parameters selecting different hardware subsets. */ + +extern int target_flags; + +/* Macros used in the machine description to test the flags. */ + +/* configure can arrage to make this 2, to force a 486. */ +#ifndef TARGET_CPU_DEFAULT +#define TARGET_CPU_DEFAULT 0 +#endif + +/* Compile 80387 insns for floating point (not library calls). */ +#define TARGET_80387 (target_flags & 1) +/* Compile code for an i486. */ +#define TARGET_486 (target_flags & 2) +/* Compile using ret insn that pops args. + This will not work unless you use prototypes at least + for all functions that can take varying numbers of args. */ +#define TARGET_RTD (target_flags & 8) +/* Compile passing first two args in regs 0 and 1. + This exists only to test compiler features that will + be needed for RISC chips. It is not usable + and is not intended to be usable on this cpu. */ +#define TARGET_REGPARM (target_flags & 020) + +/* Put uninitialized locals into bss, not data. + Meaningful only on svr3. */ +#define TARGET_SVR3_SHLIB (target_flags & 040) + +/* Use IEEE floating point comparisons. These handle correctly the cases + where the result of a comparison is unordered. Normally SIGFPE is + generated in such cases, in which case this isn't needed. */ +#define TARGET_IEEE_FP (target_flags & 0100) + +/* Functions that return a floating point value may return that value + in the 387 FPU or in 386 integer registers. If set, this flag causes + the 387 to be used, which is compatible with most calling conventions. */ +#define TARGET_FLOAT_RETURNS_IN_80387 (target_flags & 0200) + +/* Disable generation of FP sin, cos and sqrt operations for 387. + This is because FreeBSD lacks these in the math-emulator-code */ +#define TARGET_NO_FANCY_MATH_387 (target_flags & 0400) + +/* Macro to define tables used to set the flags. + This is a list in braces of pairs in braces, + each pair being { "NAME", VALUE } + where VALUE is the bits to set or minus the bits to clear. + An empty string NAME is used to identify the default VALUE. */ + +#define TARGET_SWITCHES \ + { { "80387", 1}, \ + { "no-80387", -1}, \ + { "soft-float", -1}, \ + { "no-soft-float", 1}, \ + { "486", 2}, \ + { "no-486", -2}, \ + { "386", -2}, \ + { "rtd", 8}, \ + { "no-rtd", -8}, \ + { "regparm", 020}, \ + { "no-regparm", -020}, \ + { "svr3-shlib", 040}, \ + { "no-svr3-shlib", -040}, \ + { "ieee-fp", 0100}, \ + { "no-ieee-fp", -0100}, \ + { "fp-ret-in-387", 0200}, \ + { "no-fp-ret-in-387", -0200}, \ + { "no-fancy-math-387", 0400}, \ + { "fancy-math-387", -0400}, \ + SUBTARGET_SWITCHES \ + { "", TARGET_DEFAULT | TARGET_CPU_DEFAULT}} + +/* This is meant to be redefined in the host dependent files */ +#define SUBTARGET_SWITCHES + +#define OVERRIDE_OPTIONS \ +{ \ + SUBTARGET_OVERRIDE_OPTIONS \ +} + +/* This is meant to be redefined in the host dependent files */ +#define SUBTARGET_OVERRIDE_OPTIONS + +/* target machine storage layout */ + +/* Define for XFmode extended real floating point support. + This will automatically cause REAL_ARITHMETIC to be defined. */ +#define LONG_DOUBLE_TYPE_SIZE 96 + +/* Define if you don't want extended real, but do want to use the + software floating point emulator for REAL_ARITHMETIC and + decimal <-> binary conversion. */ +/* #define REAL_ARITHMETIC */ + +/* Define this if most significant byte of a word is the lowest numbered. */ +/* That is true on the 80386. */ + +#define BITS_BIG_ENDIAN 0 + +/* Define this if most significant byte of a word is the lowest numbered. */ +/* That is not true on the 80386. */ +#define BYTES_BIG_ENDIAN 0 + +/* Define this if most significant word of a multiword number is the lowest + numbered. */ +/* Not true for 80386 */ +#define WORDS_BIG_ENDIAN 0 + +/* 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 80386, this would still be 32. + But on a machine with 16-bit registers, this would be 16. */ +#define 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. + For i486, we get better performance by aligning to a cache + line (i.e. 16 byte) boundary. */ +#define FUNCTION_BOUNDARY (TARGET_486 ? 128 : 32) + +/* Alignment of field after `int : 0' in a structure. */ + +#define EMPTY_FIELD_BOUNDARY 32 + +/* Minimum size in bits of the largest boundary to which any + and all fundamental data types supported by the hardware + might need to be aligned. No data type wants to be aligned + rounder than this. The i386 supports 64-bit floating point + quantities, but these can be aligned on any 32-bit boundary. */ +#define BIGGEST_ALIGNMENT 32 + +/* Set this non-zero if move instructions will actually fail to work + when given unaligned data. */ +#define STRICT_ALIGNMENT 0 + +/* If bit field type is int, don't let it cross an int, + and give entire struct the alignment of an int. */ +/* Required on the 386 since it doesn't have bitfield insns. */ +#define PCC_BITFIELD_TYPE_MATTERS 1 + +/* Align loop starts for optimal branching. */ +#define ASM_OUTPUT_LOOP_ALIGN(FILE) \ + ASM_OUTPUT_ALIGN (FILE, 2) + +/* This is how to align an instruction for optimal branching. + On i486 we'll get better performance by aligning on a + cache line (i.e. 16 byte) boundary. */ +#define ASM_OUTPUT_ALIGN_CODE(FILE) \ + ASM_OUTPUT_ALIGN ((FILE), (TARGET_486 ? 4 : 2)) + +/* Standard register usage. */ + +/* This processor has special stack-like registers. See reg-stack.c + for details. */ + +#define STACK_REGS + +/* Number of actual hardware registers. + The hardware registers are assigned numbers for the compiler + from 0 to just below FIRST_PSEUDO_REGISTER. + All registers that the compiler knows about must be given numbers, + even those that are not normally considered general registers. + + In the 80386 we give the 8 general purpose registers the numbers 0-7. + We number the floating point registers 8-15. + Note that registers 0-7 can be accessed as a short or int, + while only 0-3 may be used with byte `mov' instructions. + + Reg 16 does not correspond to any hardware register, but instead + appears in the RTL as an argument pointer prior to reload, and is + eliminated during reloading in favor of either the stack or frame + pointer. */ + +#define FIRST_PSEUDO_REGISTER 17 + +/* 1 for registers that have pervasive standard uses + and are not available for the register allocator. + On the 80386, the stack pointer is such, as is the arg pointer. */ +#define FIXED_REGISTERS \ +/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \ +{ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 } + +/* 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. */ + +#define CALL_USED_REGISTERS \ +/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \ +{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } + +/* Order in which to allocate registers. Each register must be + listed once, even those in FIXED_REGISTERS. List frame pointer + late and fixed registers last. Note that, in general, we prefer + registers listed in CALL_USED_REGISTERS, keeping the others + available for storage of persistent values. */ + +#define REG_ALLOC_ORDER \ +/*ax,cx,dx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \ +{ 0, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 } + +/* Macro to conditionally modify fixed_regs/call_used_regs. */ +#define CONDITIONAL_REGISTER_USAGE \ + { \ + if (flag_pic) \ + { \ + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ + call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \ + } \ + if (! TARGET_80387 && ! TARGET_FLOAT_RETURNS_IN_80387) \ + { \ + int i; \ + HARD_REG_SET x; \ + COPY_HARD_REG_SET (x, reg_class_contents[(int)FLOAT_REGS]); \ + for (i = 0; i < FIRST_PSEUDO_REGISTER; i++ ) \ + if (TEST_HARD_REG_BIT (x, i)) \ + fixed_regs[i] = call_used_regs[i] = 1; \ + } \ + } + +/* 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. + + Actually there are no two word move instructions for consecutive + registers. And only registers 0-3 may have mov byte instructions + applied to them. + */ + +#define HARD_REGNO_NREGS(REGNO, MODE) \ + (FP_REGNO_P (REGNO) ? 1 \ + : ((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. + On the 80386, the first 4 cpu registers can hold any mode + while the floating point registers may hold only floating point. + Make it clear that the fp regs could not hold a 16-byte float. */ + +/* The casts to int placate a compiler on a microvax, + for cross-compiler testing. */ + +#define HARD_REGNO_MODE_OK(REGNO, MODE) \ + ((REGNO) < 2 ? 1 \ + : (REGNO) < 4 ? 1 \ + : FP_REGNO_P (REGNO) \ + ? (((int) GET_MODE_CLASS (MODE) == (int) MODE_FLOAT \ + || (int) GET_MODE_CLASS (MODE) == (int) MODE_COMPLEX_FLOAT) \ + && GET_MODE_UNIT_SIZE (MODE) <= 12) \ + : (int) (MODE) != (int) QImode) + +/* 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) ((MODE1) == (MODE2)) + +/* A C expression returning the cost of moving data from a register of class + CLASS1 to one of CLASS2. + + On the i386, copying between floating-point and fixed-point + registers is expensive. */ + +#define REGISTER_MOVE_COST(CLASS1, CLASS2) \ + (((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2)) \ + || (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2))) ? 10 \ + : 2) + +/* Specify the registers used for certain standard purposes. + The values of these macros are register numbers. */ + +/* on the 386 the pc register is %eip, and is not usable as a general + register. The ordinary mov instructions won't work */ +/* #define PC_REGNUM */ + +/* Register to use for pushing function arguments. */ +#define STACK_POINTER_REGNUM 7 + +/* Base register for access to local variables of the function. */ +#define FRAME_POINTER_REGNUM 6 + +/* First floating point reg */ +#define FIRST_FLOAT_REG 8 + +/* First & last stack-like regs */ +#define FIRST_STACK_REG FIRST_FLOAT_REG +#define LAST_STACK_REG (FIRST_FLOAT_REG + 7) + +/* 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. + This is computed in `reload', in reload1.c. */ +#define FRAME_POINTER_REQUIRED 0 + +/* Base register for access to arguments of the function. */ +#define ARG_POINTER_REGNUM 16 + +/* Register in which static-chain is passed to a function. */ +#define STATIC_CHAIN_REGNUM 2 + +/* Register to hold the addressing base for position independent + code access to data items. */ +#define PIC_OFFSET_TABLE_REGNUM 3 + +/* Register in which address to store a structure value + arrives in the function. On the 386, the prologue + copies this from the stack to register %eax. */ +#define STRUCT_VALUE_INCOMING 0 + +/* Place in which caller passes the structure value address. + 0 means push the value on the stack like an argument. */ +#define STRUCT_VALUE 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. + + It might seem that class BREG is unnecessary, since no useful 386 + opcode needs reg %ebx. But some systems pass args to the OS in ebx, + and the "b" register constraint is useful in asms for syscalls. */ + +enum reg_class +{ + NO_REGS, + AREG, DREG, CREG, BREG, + AD_REGS, /* %eax/%edx for DImode */ + Q_REGS, /* %eax %ebx %ecx %edx */ + SIREG, DIREG, + INDEX_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp */ + GENERAL_REGS, /* %eax %ebx %ecx %edx %esi %edi %ebp %esp */ + FP_TOP_REG, FP_SECOND_REG, /* %st(0) %st(1) */ + FLOAT_REGS, + ALL_REGS, LIM_REG_CLASSES +}; + +#define N_REG_CLASSES (int) LIM_REG_CLASSES + +#define FLOAT_CLASS_P(CLASS) (reg_class_subset_p (CLASS, FLOAT_REGS)) + +/* Give names of register classes as strings for dump file. */ + +#define REG_CLASS_NAMES \ +{ "NO_REGS", \ + "AREG", "DREG", "CREG", "BREG", \ + "AD_REGS", \ + "Q_REGS", \ + "SIREG", "DIREG", \ + "INDEX_REGS", \ + "GENERAL_REGS", \ + "FP_TOP_REG", "FP_SECOND_REG", \ + "FLOAT_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 \ +{ 0, \ + 0x1, 0x2, 0x4, 0x8, /* AREG, DREG, CREG, BREG */ \ + 0x3, /* AD_REGS */ \ + 0xf, /* Q_REGS */ \ + 0x10, 0x20, /* SIREG, DIREG */ \ + 0x1007f, /* INDEX_REGS */ \ + 0x100ff, /* GENERAL_REGS */ \ + 0x0100, 0x0200, /* FP_TOP_REG, FP_SECOND_REG */ \ + 0xff00, /* FLOAT_REGS */ \ + 0x1ffff } + +/* 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. */ + +extern enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; +#define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO]) + +/* When defined, the compiler allows registers explicitly used in the + rtl to be used as spill registers but prevents the compiler from + extending the lifetime of these registers. */ + +#define SMALL_REGISTER_CLASSES + +#define QI_REG_P(X) \ + (REG_P (X) && REGNO (X) < 4) +#define NON_QI_REG_P(X) \ + (REG_P (X) && REGNO (X) >= 4 && REGNO (X) < FIRST_PSEUDO_REGISTER) + +#define FP_REG_P(X) (REG_P (X) && FP_REGNO_P (REGNO (X))) +#define FP_REGNO_P(n) ((n) >= FIRST_STACK_REG && (n) <= LAST_STACK_REG) + +#define STACK_REG_P(xop) (REG_P (xop) && \ + REGNO (xop) >= FIRST_STACK_REG && \ + REGNO (xop) <= LAST_STACK_REG) + +#define NON_STACK_REG_P(xop) (REG_P (xop) && ! STACK_REG_P (xop)) + +#define STACK_TOP_P(xop) (REG_P (xop) && REGNO (xop) == FIRST_STACK_REG) + +/* Try to maintain the accuracy of the death notes for regs satisfying the + following. Important for stack like regs, to know when to pop. */ + +/* #define PRESERVE_DEATH_INFO_REGNO_P(x) FP_REGNO_P(x) */ + +/* 1 if register REGNO can magically overlap other regs. + Note that nonzero values work only in very special circumstances. */ + +/* #define OVERLAPPING_REGNO_P(REGNO) FP_REGNO_P (REGNO) */ + +/* The class value for index registers, and the one for base regs. */ + +#define INDEX_REG_CLASS INDEX_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) == 'r' ? GENERAL_REGS : \ + (C) == 'q' ? Q_REGS : \ + (C) == 'f' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \ + ? FLOAT_REGS \ + : NO_REGS) : \ + (C) == 't' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \ + ? FP_TOP_REG \ + : NO_REGS) : \ + (C) == 'u' ? (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387 \ + ? FP_SECOND_REG \ + : NO_REGS) : \ + (C) == 'a' ? AREG : \ + (C) == 'b' ? BREG : \ + (C) == 'c' ? CREG : \ + (C) == 'd' ? DREG : \ + (C) == 'A' ? AD_REGS : \ + (C) == 'D' ? DIREG : \ + (C) == 'S' ? SIREG : 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 is for non-DImode shifts. + J is for DImode shifts. + K and L are for an `andsi' optimization. + M is for shifts that can be executed by the "lea" opcode. + */ + +#define CONST_OK_FOR_LETTER_P(VALUE, C) \ + ((C) == 'I' ? (VALUE) >= 0 && (VALUE) <= 31 : \ + (C) == 'J' ? (VALUE) >= 0 && (VALUE) <= 63 : \ + (C) == 'K' ? (VALUE) == 0xff : \ + (C) == 'L' ? (VALUE) == 0xffff : \ + (C) == 'M' ? (VALUE) >= 0 && (VALUE) <= 3 : \ + 0) + +/* Similar, but for floating constants, and defining letters G and H. + Here VALUE is the CONST_DOUBLE rtx itself. We allow constants even if + TARGET_387 isn't set, because the stack register converter may need to + load 0.0 into the function value register. */ + +#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \ + ((C) == 'G' ? standard_80387_constant_p (VALUE) : 0) + +/* Place additional restrictions on the register class to use when it + is necessary to be able to hold a value of mode MODE in a reload + register for which class CLASS would ordinarily be used. */ + +#define LIMIT_RELOAD_CLASS(MODE, CLASS) \ + ((MODE) == QImode && ((CLASS) == ALL_REGS || (CLASS) == GENERAL_REGS) \ + ? Q_REGS : (CLASS)) + +/* 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. + On the 80386 series, we prevent floating constants from being + reloaded into floating registers (since no move-insn can do that) + and we ensure that QImodes aren't reloaded into the esi or edi reg. */ + +/* Put float CONST_DOUBLE in the constant pool instead of fp regs. + QImode must go into class Q_REGS. + Narrow ALL_REGS to GENERAL_REGS. This supports allowing movsf and + movdf to do mem-to-mem moves through integer regs. */ + +#define PREFERRED_RELOAD_CLASS(X,CLASS) \ + (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode ? NO_REGS \ + : GET_MODE (X) == QImode && ! reg_class_subset_p (CLASS, Q_REGS) ? Q_REGS \ + : ((CLASS) == ALL_REGS \ + && GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) ? GENERAL_REGS \ + : (CLASS)) + +/* If we are copying between general and FP registers, we need a memory + location. */ + +#define SECONDARY_MEMORY_NEEDED(CLASS1,CLASS2,MODE) \ + ((FLOAT_CLASS_P (CLASS1) && ! FLOAT_CLASS_P (CLASS2)) \ + || (! FLOAT_CLASS_P (CLASS1) && FLOAT_CLASS_P (CLASS2))) + +/* Return the maximum number of consecutive registers + needed to represent mode MODE in a register of class CLASS. */ +/* On the 80386, this is the size of MODE in words, + except in the FP regs, where a single reg is always enough. */ +#define CLASS_MAX_NREGS(CLASS, MODE) \ + (FLOAT_CLASS_P (CLASS) ? 1 : \ + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) + +/* 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 + +/* Define this if the nominal address of the stack frame + is at the high-address end of the local variables; + that is, each additional local variable allocated + goes at a more negative offset in the frame. */ +#define FRAME_GROWS_DOWNWARD + +/* Offset within stack frame to start allocating local variables at. + If FRAME_GROWS_DOWNWARD, this is the offset to the END of the + first local allocated. Otherwise, it is the offset to the BEGINNING + of the first local 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. + On 386 pushw decrements by exactly 2 no matter what the position was. + On the 386 there is no pushb; we use pushw instead, and this + has the effect of rounding up to 2. */ + +#define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & (-2)) + +/* Offset of first parameter from the argument pointer register value. */ +#define FIRST_PARM_OFFSET(FNDECL) 0 + +/* Value is the number of bytes of arguments automatically + popped when returning from a subroutine call. + 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. + + On the 80386, the RTD insn may be used to pop them if the number + of args is fixed, but if the number is variable then the caller + must pop them all. RTD can't be used for library calls now + because the library is compiled with the Unix compiler. + Use of RTD is a selectable option, since it is incompatible with + standard Unix calling sequences. If the option is not selected, + the caller must always pop the args. */ + +#define RETURN_POPS_ARGS(FUNTYPE,SIZE) \ + (TREE_CODE (FUNTYPE) == IDENTIFIER_NODE ? 0 \ + : (TARGET_RTD \ + && (TYPE_ARG_TYPES (FUNTYPE) == 0 \ + || (TREE_VALUE (tree_last (TYPE_ARG_TYPES (FUNTYPE))) \ + == void_type_node))) ? (SIZE) \ + : (aggregate_value_p (TREE_TYPE (FUNTYPE))) ? GET_MODE_SIZE (Pmode) : 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), \ + VALUE_REGNO (TYPE_MODE (VALTYPE))) + +/* 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, VALUE_REGNO (MODE)) + +/* Define the size of the result block used for communication between + untyped_call and untyped_return. The block contains a DImode value + followed by the block used by fnsave and frstor. */ + +#define APPLY_RESULT_SIZE (8+108) + +/* 1 if N is a possible register number for function argument passing. + On the 80386, no registers are used in this way. + *NOTE* -mregparm does not work. + It exists only to test register calling conventions. */ + +#define FUNCTION_ARG_REGNO_P(N) 0 + +/* 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. + + On the 80386, this is a single integer, which is a number of bytes + of arguments scanned so far. */ + +#define CUMULATIVE_ARGS int + +/* 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. + + On the 80386, the offset starts at 0. */ + +#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME) \ + ((CUM) = 0) + +/* Update the data in CUM to advance over an argument + of mode MODE and data type TYPE. + (TYPE is null for libcalls where that information may not be available.) */ + +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ + ((CUM) += ((MODE) != BLKmode \ + ? (GET_MODE_SIZE (MODE) + 3) & ~3 \ + : (int_size_in_bytes (TYPE) + 3) & ~3)) + +/* 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). */ + + +/* On the 80386 all args are pushed, except if -mregparm is specified + then the first two words of arguments are passed in EAX, EDX. + *NOTE* -mregparm does not work. + It exists only to test register calling conventions. */ + +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \ +((TARGET_REGPARM && (CUM) < 8) ? gen_rtx (REG, (MODE), (CUM) / 4) : 0) + +/* For an arg passed partly in registers and partly in memory, + this is the number of registers used. + For args passed entirely in registers or entirely in memory, zero. */ + + +#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) \ +((TARGET_REGPARM && (CUM) < 8 \ + && 8 < ((CUM) + ((MODE) == BLKmode \ + ? int_size_in_bytes (TYPE) \ + : GET_MODE_SIZE (MODE)))) \ + ? 2 - (CUM) / 4 : 0) + +/* This macro generates the assembly code for function entry. + FILE is a stdio stream to output the code to. + SIZE is an int: how many units of temporary storage to allocate. + Refer to the array `regs_ever_live' to determine which registers + to save; `regs_ever_live[I]' is nonzero if register number I + is ever used in the function. This macro is responsible for + knowing which registers should not be saved even if used. */ + +#define FUNCTION_PROLOGUE(FILE, SIZE) \ + function_prologue (FILE, SIZE) + +/* Output assembler code to FILE to increment profiler label # LABELNO + for profiling a function entry. */ + +#define FUNCTION_PROFILER(FILE, LABELNO) \ +{ \ + if (flag_pic) \ + { \ + fprintf (FILE, "\tleal %sP%d@GOTOFF(%%ebx),%%edx\n", \ + LPREFIX, (LABELNO)); \ + fprintf (FILE, "\tcall *_mcount@GOT(%%ebx)\n"); \ + } \ + else \ + { \ + fprintf (FILE, "\tmovl $%sP%d,%%edx\n", LPREFIX, (LABELNO)); \ + fprintf (FILE, "\tcall _mcount\n"); \ + } \ +} + +/* 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. */ +/* Note on the 386 it might be more efficient not to define this since + we have to restore it ourselves from the frame pointer, in order to + use pop */ + +#define EXIT_IGNORE_STACK 1 + +/* This macro generates the assembly code for function exit, + on machines that need it. If FUNCTION_EPILOGUE is not defined + then individual return instructions are generated for each + return statement. Args are same as for FUNCTION_PROLOGUE. + + The function epilogue should not depend on the current stack pointer! + It should use the frame pointer only. This is mandatory because + of alloca; we also take advantage of it to omit stack adjustments + before returning. + + If the last non-note insn in the function is a BARRIER, then there + is no need to emit a function prologue, because control does not fall + off the end. This happens if the function ends in an "exit" call, or + if a `return' insn is emitted directly into the function. */ + +#define FUNCTION_EPILOGUE(FILE, SIZE) \ +do { \ + rtx last = get_last_insn (); \ + if (last && GET_CODE (last) == NOTE) \ + last = prev_nonnote_insn (last); \ + if (! last || GET_CODE (last) != BARRIER) \ + function_epilogue (FILE, SIZE); \ +} while (0) + +/* Output assembler code for a block containing the constant parts + of a trampoline, leaving space for the variable parts. */ + +/* On the 386, the trampoline contains three instructions: + mov #STATIC,ecx + mov #FUNCTION,eax + jmp @eax */ +#define TRAMPOLINE_TEMPLATE(FILE) \ +{ \ + ASM_OUTPUT_CHAR (FILE, GEN_INT (0xb9)); \ + ASM_OUTPUT_SHORT (FILE, const0_rtx); \ + ASM_OUTPUT_SHORT (FILE, const0_rtx); \ + ASM_OUTPUT_CHAR (FILE, GEN_INT (0xb8)); \ + ASM_OUTPUT_SHORT (FILE, const0_rtx); \ + ASM_OUTPUT_SHORT (FILE, const0_rtx); \ + ASM_OUTPUT_CHAR (FILE, GEN_INT (0xff)); \ + ASM_OUTPUT_CHAR (FILE, GEN_INT (0xe0)); \ +} + +/* Length in units of the trampoline for entering a nested function. */ + +#define TRAMPOLINE_SIZE 12 + +/* 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) \ +{ \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 1)), CXT); \ + emit_move_insn (gen_rtx (MEM, SImode, plus_constant (TRAMP, 6)), FNADDR); \ +} + +/* Definitions for register eliminations. + + 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. + + We have two registers that can be eliminated on the i386. First, the + frame pointer register can often be eliminated in favor of the stack + pointer register. Secondly, the argument pointer register can always be + eliminated; it is replaced with either the stack or frame pointer. */ + +#define ELIMINABLE_REGS \ +{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \ + { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \ + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}} + +/* Given FROM and TO register numbers, say whether this elimination is allowed. + Frame pointer elimination is automatically handled. + + For the i386, if frame pointer elimination is being done, we would like to + convert ap into sp, not fp. + + All other eliminations are valid. */ + +#define CAN_ELIMINATE(FROM, TO) \ + ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM \ + ? ! frame_pointer_needed \ + : 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) \ +{ \ + if ((FROM) == ARG_POINTER_REGNUM && (TO) == FRAME_POINTER_REGNUM) \ + (OFFSET) = 8; /* Skip saved PC and previous frame pointer */ \ + else \ + { \ + int regno; \ + int offset = 0; \ + \ + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) \ + if ((regs_ever_live[regno] && ! call_used_regs[regno]) \ + || (current_function_uses_pic_offset_table \ + && regno == PIC_OFFSET_TABLE_REGNUM)) \ + offset += 4; \ + \ + (OFFSET) = offset + get_frame_size (); \ + \ + if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM) \ + (OFFSET) += 4; /* Skip saved PC */ \ + } \ +} + +/* Addressing modes, and classification of registers for them. */ + +/* #define HAVE_POST_INCREMENT */ +/* #define HAVE_POST_DECREMENT */ + +/* #define HAVE_PRE_DECREMENT */ +/* #define HAVE_PRE_INCREMENT */ + +/* Macros to check register numbers against specific register classes. */ + +/* 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. */ + +#define REGNO_OK_FOR_INDEX_P(REGNO) \ + ((REGNO) < STACK_POINTER_REGNUM \ + || (unsigned) reg_renumber[REGNO] < STACK_POINTER_REGNUM) + +#define REGNO_OK_FOR_BASE_P(REGNO) \ + ((REGNO) <= STACK_POINTER_REGNUM \ + || (REGNO) == ARG_POINTER_REGNUM \ + || (unsigned) reg_renumber[REGNO] <= STACK_POINTER_REGNUM) + +#define REGNO_OK_FOR_SIREG_P(REGNO) ((REGNO) == 4 || reg_renumber[REGNO] == 4) +#define REGNO_OK_FOR_DIREG_P(REGNO) ((REGNO) == 5 || reg_renumber[REGNO] == 5) + +/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx + and check its validity for a certain class. + We have two alternate definitions for each of them. + The usual definition accepts all pseudo regs; the other rejects + them unless they have been allocated suitable hard regs. + The symbol REG_OK_STRICT causes the latter definition to be used. + + Most source files want to accept pseudo regs in the hope that + they will get allocated to the class that the insn wants them to be in. + Source files for reload pass need to be strict. + After reload, it makes no difference, since pseudo regs have + been eliminated by then. */ + +#ifndef REG_OK_STRICT + +/* Nonzero if X is a hard reg that can be used as an index or if + it is a pseudo reg. */ + +#define REG_OK_FOR_INDEX_P(X) \ + (REGNO (X) < STACK_POINTER_REGNUM \ + || REGNO (X) >= FIRST_PSEUDO_REGISTER) + +/* Nonzero if X is a hard reg that can be used as a base reg + of if it is a pseudo reg. */ + /* ?wfs */ + +#define REG_OK_FOR_BASE_P(X) \ + (REGNO (X) <= STACK_POINTER_REGNUM \ + || REGNO (X) == ARG_POINTER_REGNUM \ + || REGNO(X) >= FIRST_PSEUDO_REGISTER) + +#define REG_OK_FOR_STRREG_P(X) \ + (REGNO (X) == 4 || REGNO (X) == 5 || REGNO (X) >= FIRST_PSEUDO_REGISTER) + +#else + +/* Nonzero if X is a hard reg that can be used as an index. */ +#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) +/* Nonzero if X is a hard reg that can be used as a base reg. */ +#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X)) +#define REG_OK_FOR_STRREG_P(X) \ + (REGNO_OK_FOR_DIREG_P (REGNO (X)) || REGNO_OK_FOR_SIREG_P (REGNO (X))) + +#endif + +/* 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. + + The other macros defined here are used only in GO_IF_LEGITIMATE_ADDRESS, + except for CONSTANT_ADDRESS_P which is usually machine-independent. + + See legitimize_pic_address in i386.c for details as to what + constitutes a legitimate address when -fpic is used. */ + +#define MAX_REGS_PER_ADDRESS 2 + +#define CONSTANT_ADDRESS_P(X) \ + (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ + || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \ + || GET_CODE (X) == HIGH) + +/* Nonzero if the constant value X is a legitimate general operand. + It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ + +#define LEGITIMATE_CONSTANT_P(X) 1 + +#define GO_IF_INDEXABLE_BASE(X, ADDR) \ + if (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X)) goto ADDR + +#define LEGITIMATE_INDEX_REG_P(X) \ + (GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X)) + +/* Return 1 if X is an index or an index times a scale. */ + +#define LEGITIMATE_INDEX_P(X) \ + (LEGITIMATE_INDEX_REG_P (X) \ + || (GET_CODE (X) == MULT \ + && LEGITIMATE_INDEX_REG_P (XEXP (X, 0)) \ + && GET_CODE (XEXP (X, 1)) == CONST_INT \ + && (INTVAL (XEXP (X, 1)) == 2 \ + || INTVAL (XEXP (X, 1)) == 4 \ + || INTVAL (XEXP (X, 1)) == 8))) + +/* Go to ADDR if X is an index term, a base reg, or a sum of those. */ + +#define GO_IF_INDEXING(X, ADDR) \ +{ if (LEGITIMATE_INDEX_P (X)) goto ADDR; \ + GO_IF_INDEXABLE_BASE (X, ADDR); \ + if (GET_CODE (X) == PLUS && LEGITIMATE_INDEX_P (XEXP (X, 0))) \ + { GO_IF_INDEXABLE_BASE (XEXP (X, 1), ADDR); } \ + if (GET_CODE (X) == PLUS && LEGITIMATE_INDEX_P (XEXP (X, 1))) \ + { GO_IF_INDEXABLE_BASE (XEXP (X, 0), ADDR); } } + +/* We used to allow this, but it isn't ever used. + || ((GET_CODE (X) == POST_DEC || GET_CODE (X) == POST_INC) \ + && REG_P (XEXP (X, 0)) \ + && REG_OK_FOR_STRREG_P (XEXP (X, 0))) \ +*/ + +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \ +{ \ + if (CONSTANT_ADDRESS_P (X) \ + && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (X))) \ + goto ADDR; \ + GO_IF_INDEXING (X, ADDR); \ + if (GET_CODE (X) == PLUS && CONSTANT_ADDRESS_P (XEXP (X, 1))) \ + { \ + rtx x0 = XEXP (X, 0); \ + if (! flag_pic || ! SYMBOLIC_CONST (XEXP (X, 1))) \ + { GO_IF_INDEXING (x0, ADDR); } \ + else if (x0 == pic_offset_table_rtx) \ + goto ADDR; \ + else if (GET_CODE (x0) == PLUS) \ + { \ + if (XEXP (x0, 0) == pic_offset_table_rtx) \ + { GO_IF_INDEXABLE_BASE (XEXP (x0, 1), ADDR); } \ + if (XEXP (x0, 1) == pic_offset_table_rtx) \ + { GO_IF_INDEXABLE_BASE (XEXP (x0, 0), ADDR); } \ + } \ + } \ +} + +/* 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. + + For the 80386, we handle X+REG by loading X into a register R and + using R+REG. R will go in a general reg and indexing will be used. + However, if REG is a broken-out memory address or multiplication, + nothing needs to be done because REG can certainly go in a general reg. + + When -fpic is used, special handling is needed for symbolic references. + See comments by legitimize_pic_address in i386.c for details. */ + +#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \ +{ extern rtx legitimize_pic_address (); \ + int ch = (X) != (OLDX); \ + if (flag_pic && SYMBOLIC_CONST (X)) \ + { \ + (X) = legitimize_pic_address (X, 0); \ + if (memory_address_p (MODE, X)) \ + goto WIN; \ + } \ + if (GET_CODE (X) == PLUS) \ + { if (GET_CODE (XEXP (X, 0)) == MULT) \ + ch = 1, XEXP (X, 0) = force_operand (XEXP (X, 0), 0); \ + if (GET_CODE (XEXP (X, 1)) == MULT) \ + ch = 1, XEXP (X, 1) = force_operand (XEXP (X, 1), 0); \ + if (ch && GET_CODE (XEXP (X, 1)) == REG \ + && GET_CODE (XEXP (X, 0)) == REG) \ + goto WIN; \ + if (flag_pic && SYMBOLIC_CONST (XEXP (X, 1))) \ + ch = 1, (X) = legitimize_pic_address (X, 0); \ + if (ch) { GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); } \ + if (GET_CODE (XEXP (X, 0)) == REG) \ + { register rtx temp = gen_reg_rtx (Pmode); \ + register rtx val = force_operand (XEXP (X, 1), temp); \ + if (val != temp) emit_move_insn (temp, val); \ + XEXP (X, 1) = temp; \ + goto WIN; } \ + else if (GET_CODE (XEXP (X, 1)) == REG) \ + { register rtx temp = gen_reg_rtx (Pmode); \ + register rtx val = force_operand (XEXP (X, 0), temp); \ + if (val != temp) emit_move_insn (temp, val); \ + XEXP (X, 0) = temp; \ + goto WIN; }}} + +/* Nonzero if the constant value X is a legitimate general operand + when generating PIC code. It is given that flag_pic is on and + that X satisfies CONSTANT_P or is a CONST_DOUBLE. */ + +#define LEGITIMATE_PIC_OPERAND_P(X) \ + (! SYMBOLIC_CONST (X) \ + || (GET_CODE (X) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (X))) + +#define SYMBOLIC_CONST(X) \ +(GET_CODE (X) == SYMBOL_REF \ + || GET_CODE (X) == LABEL_REF \ + || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X))) + +/* Go to LABEL if ADDR (a legitimate address expression) + has an effect that depends on the machine mode it is used for. + On the 80386, only postdecrement and postincrement address depend thus + (the amount of decrement or increment being the length of the operand). */ +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \ + if (GET_CODE (ADDR) == POST_INC || GET_CODE (ADDR) == POST_DEC) goto LABEL + +/* Define this macro if references to a symbol must be treated + differently depending on something about the variable or + function named by the symbol (such as what section it is in). + + On i386, if using PIC, mark a SYMBOL_REF for a non-global symbol + so that we may access it directly in the GOT. */ + +#define ENCODE_SECTION_INFO(DECL) \ +do \ + { \ + if (flag_pic) \ + { \ + rtx rtl = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + ? TREE_CST_RTL (DECL) : DECL_RTL (DECL)); \ + SYMBOL_REF_FLAG (XEXP (rtl, 0)) \ + = (TREE_CODE_CLASS (TREE_CODE (DECL)) != 'd' \ + || ! TREE_PUBLIC (DECL)); \ + } \ + } \ +while (0) + +/* Initialize data used by insn expanders. This is called from + init_emit, once for each function, before code is generated. + For 386, clear stack slot assignments remembered from previous + functions. */ + +#define INIT_EXPANDERS clear_386_stack_locals () + +/* The `FINALIZE_PIC' macro serves as a hook to emit these special + codes once the function is being compiled into assembly code, but + not before. (It is not done before, because in the case of + compiling an inline function, it would lead to multiple PIC + prologues being included in functions which used inline functions + and were compiled to assembly language.) */ + +#define FINALIZE_PIC \ +do \ + { \ + extern int current_function_uses_pic_offset_table; \ + \ + current_function_uses_pic_offset_table |= profile_flag | profile_block_flag; \ + } \ +while (0) + + +/* Specify the machine mode that this machine uses + for the index in the tablejump instruction. */ +#define CASE_VECTOR_MODE Pmode + +/* Define this if the tablejump instruction expects the table + to contain offsets from the address of the table. + Do not define this if the table should contain absolute addresses. */ +/* #define CASE_VECTOR_PC_RELATIVE */ + +/* Specify the tree operation to be used to convert reals to integers. + This should be changed to take advantage of fist --wfs ?? + */ +#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 + +/* Define this as 1 if `char' should by default be signed; else as 0. */ +#define DEFAULT_SIGNED_CHAR 1 + +/* Max number of bytes we can move from memory to memory + in one reasonably fast instruction. */ +#define MOVE_MAX 4 + +/* MOVE_RATIO is the number of move instructions that is better than a + block move. Make this large on i386, since the block move is very + inefficient with small blocks, and the hard register needs of the + block move require much reload work. */ +#define MOVE_RATIO 5 + +/* Define this if zero-extension is slow (more than one real instruction). */ +/* #define SLOW_ZERO_EXTEND */ + +/* Nonzero if access to memory by bytes is slow and undesirable. */ +#define SLOW_BYTE_ACCESS 0 + +/* Define if shifts truncate the shift count + which implies one can omit a sign-extension or zero-extension + of a shift count. */ +/* One i386, shifts do truncate the count. But bit opcodes don't. */ + +/* #define SHIFT_COUNT_TRUNCATED */ + +/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits + is done just by pretending it is already truncated. */ +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 + +/* We assume that the store-condition-codes instructions store 0 for false + and some other value for true. This is the value stored for true. */ + +#define STORE_FLAG_VALUE 1 + +/* When a prototype says `char' or `short', really pass an `int'. + (The 386 can't easily push less than an int.) */ + +#define PROMOTE_PROTOTYPES + +/* Specify the machine mode that pointers have. + After generation of rtl, the compiler makes no further distinction + between pointers and any other objects of this machine mode. */ +#define Pmode SImode + +/* A function address in a call instruction + is a byte address (for indexing purposes) + so give the MEM rtx a byte's mode. */ +#define FUNCTION_MODE QImode + +/* Define this if addresses of constant functions + shouldn't be put through pseudo regs where they can be cse'd. + Desirable on the 386 because a CALL with a constant address is + not much slower than one with a register address. */ +#define NO_FUNCTION_CSE + +/* Provide the costs of a rtl expression. This is in the body of a + switch on CODE. */ + +#define RTX_COSTS(X,CODE,OUTER_CODE) \ + case MULT: \ + return COSTS_N_INSNS (10); \ + case DIV: \ + case UDIV: \ + case MOD: \ + case UMOD: \ + return COSTS_N_INSNS (40); \ + case PLUS: \ + if (GET_CODE (XEXP (X, 0)) == REG \ + && GET_CODE (XEXP (X, 1)) == CONST_INT) \ + return 1; \ + break; + + +/* Compute the cost of computing a constant rtl expression RTX + whose rtx-code is CODE. The body of this macro is a portion + of a switch statement. If the code is computed here, + return it with a return statement. Otherwise, break from the switch. */ + +#define CONST_COSTS(RTX,CODE,OUTER_CODE) \ + case CONST_INT: \ + case CONST: \ + case LABEL_REF: \ + case SYMBOL_REF: \ + return flag_pic && SYMBOLIC_CONST (RTX) ? 2 : 0; \ + case CONST_DOUBLE: \ + { \ + int code; \ + if (GET_MODE (RTX) == VOIDmode) \ + return 2; \ + code = standard_80387_constant_p (RTX); \ + return code == 1 ? 0 : \ + code == 2 ? 1 : \ + 2; \ + } + +/* Compute the cost of an address. This is meant to approximate the size + and/or execution delay of an insn using that address. If the cost is + approximated by the RTL complexity, including CONST_COSTS above, as + is usually the case for CISC machines, this macro should not be defined. + For aggressively RISCy machines, only one insn format is allowed, so + this macro should be a constant. The value of this macro only matters + for valid addresses. + + For i386, it is better to use a complex address than let gcc copy + the address into a reg and make a new pseudo. But not if the address + requires to two regs - that would mean more pseudos with longer + lifetimes. */ + +#define ADDRESS_COST(RTX) \ + ((CONSTANT_P (RTX) \ + || (GET_CODE (RTX) == PLUS && CONSTANT_P (XEXP (RTX, 1)) \ + && REG_P (XEXP (RTX, 0)))) ? 0 \ + : REG_P (RTX) ? 1 \ + : 2) + +/* Add any extra modes needed to represent the condition code. + + For the i386, we need separate modes when floating-point equality + comparisons are being done. */ + +#define EXTRA_CC_MODES CCFPEQmode + +/* Define the names for the modes specified above. */ +#define EXTRA_CC_NAMES "CCFPEQ" + +/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE, + return the mode to be used for the comparison. + + For floating-point equality comparisons, CCFPEQmode should be used. + VOIDmode should be used in all other cases. */ + +#define SELECT_CC_MODE(OP,X,Y) \ + (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT \ + && ((OP) == EQ || (OP) == NE) ? CCFPEQmode : VOIDmode) + +/* Define the information needed to generate branch and scc insns. This is + stored from the compare operation. Note that we can't use "rtx" here + since it hasn't been defined! */ + +extern struct rtx_def *i386_compare_op0, *i386_compare_op1; +extern struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)(); + +/* Tell final.c how to eliminate redundant test instructions. */ + +/* Here we define machine-dependent flags and fields in cc_status + (see `conditions.h'). */ + +/* Set if the cc value is actually in the 80387, so a floating point + conditional branch must be output. */ +#define CC_IN_80387 04000 + +/* Set if the CC value was stored in a nonstandard way, so that + the state of equality is indicated by zero in the carry bit. */ +#define CC_Z_IN_NOT_C 010000 + +/* Store in cc_status the expressions + that the condition codes will describe + after execution of an instruction whose pattern is EXP. + Do not alter them if the instruction would not alter the cc's. */ + +#define NOTICE_UPDATE_CC(EXP, INSN) \ + notice_update_cc((EXP)) + +/* Output a signed jump insn. Use template NORMAL ordinarily, or + FLOAT following a floating point comparison. + Use NO_OV following an arithmetic insn that set the cc's + before a test insn that was deleted. + NO_OV may be zero, meaning final should reinsert the test insn + because the jump cannot be handled properly without it. */ + +#define OUTPUT_JUMP(NORMAL, FLOAT, NO_OV) \ +{ \ + if (cc_prev_status.flags & CC_IN_80387) \ + return FLOAT; \ + if (cc_prev_status.flags & CC_NO_OVERFLOW) \ + return NO_OV; \ + return NORMAL; \ +} + +/* Control the assembler format that we output, to the extent + this does not vary between assemblers. */ + +/* How to refer to registers in assembler output. + This sequence is indexed by compiler's hard-register-number (see above). */ + +/* In order to refer to the first 8 regs as 32 bit regs prefix an "e" + For non floating point regs, the following are the HImode names. + + For float regs, the stack top is sometimes referred to as "%st(0)" + instead of just "%st". PRINT_REG handles this with the "y" code. */ + +#define HI_REGISTER_NAMES \ +{"ax","dx","cx","bx","si","di","bp","sp", \ + "st","st(1)","st(2)","st(3)","st(4)","st(5)","st(6)","st(7)","" } + +#define REGISTER_NAMES HI_REGISTER_NAMES + +/* Table of additional register names to use in user input. */ + +#define ADDITIONAL_REGISTER_NAMES \ +{ "eax", 0, "edx", 1, "ecx", 2, "ebx", 3, \ + "esi", 4, "edi", 5, "ebp", 6, "esp", 7, \ + "al", 0, "dl", 1, "cl", 2, "bl", 3, \ + "ah", 0, "dh", 1, "ch", 2, "bh", 3 } + +/* Note we are omitting these since currently I don't know how +to get gcc to use these, since they want the same but different +number as al, and ax. +*/ + +/* note the last four are not really qi_registers, but + the md will have to never output movb into one of them + only a movw . There is no movb into the last four regs */ + +#define QI_REGISTER_NAMES \ +{"al", "dl", "cl", "bl", "si", "di", "bp", "sp",} + +/* These parallel the array above, and can be used to access bits 8:15 + of regs 0 through 3. */ + +#define QI_HIGH_REGISTER_NAMES \ +{"ah", "dh", "ch", "bh", } + +/* How to renumber registers for dbx and gdb. */ + +/* {0,2,1,3,6,7,4,5,12,13,14,15,16,17} */ +#define DBX_REGISTER_NUMBER(n) \ +((n) == 0 ? 0 : \ + (n) == 1 ? 2 : \ + (n) == 2 ? 1 : \ + (n) == 3 ? 3 : \ + (n) == 4 ? 6 : \ + (n) == 5 ? 7 : \ + (n) == 6 ? 4 : \ + (n) == 7 ? 5 : \ + (n) + 4) + +/* This is how to output the definition of a user-level label named NAME, + such as the label on a static function or variable NAME. */ + +#define ASM_OUTPUT_LABEL(FILE,NAME) \ + (assemble_name (FILE, NAME), fputs (":\n", FILE)) + +/* This is how to output an assembler line defining a `double' constant. */ + +#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \ +do { long l[2]; \ + REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \ + if (sizeof (int) == sizeof (long)) \ + fprintf (FILE, "%s 0x%x,0x%x\n", ASM_LONG, l[0], l[1]); \ + else \ + fprintf (FILE, "%s 0x%lx,0x%lx\n", ASM_LONG, l[0], l[1]); \ + } while (0) + +/* This is how to output a `long double' extended real constant. */ + +#undef ASM_OUTPUT_LONG_DOUBLE +#define ASM_OUTPUT_LONG_DOUBLE(FILE,VALUE) \ +do { long l[3]; \ + REAL_VALUE_TO_TARGET_LONG_DOUBLE (VALUE, l); \ + if (sizeof (int) == sizeof (long)) \ + fprintf (FILE, "%s 0x%x,0x%x,0x%x\n", ASM_LONG, l[0], l[1], l[2]); \ + else \ + fprintf (FILE, "%s 0x%lx,0x%lx,0x%lx\n", ASM_LONG, l[0], l[1], l[2]); \ + } while (0) + +/* This is how to output an assembler line defining a `float' constant. */ + +#define ASM_OUTPUT_FLOAT(FILE,VALUE) \ +do { long l; \ + REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \ + if (sizeof (int) == sizeof (long)) \ + fprintf ((FILE), "%s 0x%x\n", ASM_LONG, l); \ + else \ + fprintf ((FILE), "%s 0x%lx\n", ASM_LONG, l); \ + } while (0) + +/* Store in OUTPUT a string (made with alloca) containing + an assembler-name for a local static variable named NAME. + LABELNO is an integer which is different for each call. */ + +#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ +( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ + sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO))) + + + +/* This is how to output an assembler line defining an `int' constant. */ + +#define ASM_OUTPUT_INT(FILE,VALUE) \ +( fprintf (FILE, "%s ", ASM_LONG), \ + output_addr_const (FILE,(VALUE)), \ + putc('\n',FILE)) + +/* Likewise for `char' and `short' constants. */ +/* is this supposed to do align too?? */ + +#define ASM_OUTPUT_SHORT(FILE,VALUE) \ +( fprintf (FILE, "%s ", ASM_SHORT), \ + output_addr_const (FILE,(VALUE)), \ + putc('\n',FILE)) + +/* +#define ASM_OUTPUT_SHORT(FILE,VALUE) \ +( fprintf (FILE, "%s ", ASM_BYTE_OP), \ + output_addr_const (FILE,(VALUE)), \ + fputs (",", FILE), \ + output_addr_const (FILE,(VALUE)), \ + fputs (" >> 8\n",FILE)) +*/ + + +#define ASM_OUTPUT_CHAR(FILE,VALUE) \ +( fprintf (FILE, "%s ", ASM_BYTE_OP), \ + output_addr_const (FILE, (VALUE)), \ + putc ('\n', FILE)) + +/* This is how to output an assembler line for a numeric constant byte. */ + +#define ASM_OUTPUT_BYTE(FILE,VALUE) \ + fprintf ((FILE), "%s 0x%x\n", ASM_BYTE_OP, (VALUE)) + +/* This is how to output an insn to push a register on the stack. + It need not be very fast code. */ + +#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ + fprintf (FILE, "\tpushl e%s\n", reg_names[REGNO]) + +/* This is how to output an insn to pop a register from the stack. + It need not be very fast code. */ + +#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ + fprintf (FILE, "\tpopl e%s\n", reg_names[REGNO]) + +/* This is how to output an element of a case-vector that is absolute. + */ + +#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \ + fprintf (FILE, "%s %s%d\n", ASM_LONG, LPREFIX, VALUE) + +/* This is how to output an element of a case-vector that is relative. + We don't use these on the 386 yet, because the ATT assembler can't do + forward reference the differences. + */ + +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ + fprintf (FILE, "\t.word %s%d-%s%d\n",LPREFIX, VALUE,LPREFIX, REL) + +/* Define the parentheses used to group arithmetic operations + in assembler code. */ + +#define ASM_OPEN_PAREN "" +#define ASM_CLOSE_PAREN "" + +/* Define results of standard character escape sequences. */ +#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 dot (`z' in `%z0') or 0 if no letter was specified. + The CODE z takes the size of operand from the following digit, and + outputs b,w,or l respectively. + + On the 80386, we use several such letters: + f -- float insn (print a CONST_DOUBLE as a float rather than in hex). + L,W,B,Q,S,T -- print the opcode suffix for specified size of operand. + R -- print the prefix for register names. + z -- print the opcode suffix for the size of the current operand. + * -- print a star (in certain assembler syntax) + w -- print the operand as if it's a "word" (HImode) even if it isn't. + b -- print the operand as if it's a byte (QImode) even if it isn't. + c -- don't print special prefixes before constant operands. */ + +#define PRINT_OPERAND_PUNCT_VALID_P(CODE) \ + ((CODE) == '*') + +/* Print the name of a register based on its machine mode and number. + If CODE is 'w', pretend the mode is HImode. + If CODE is 'b', pretend the mode is QImode. + If CODE is 'k', pretend the mode is SImode. + If CODE is 'h', pretend the reg is the `high' byte register. + If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op. */ + +extern char *hi_reg_name[]; +extern char *qi_reg_name[]; +extern char *qi_high_reg_name[]; + +#define PRINT_REG(X, CODE, FILE) \ + do { if (REGNO (X) == ARG_POINTER_REGNUM) \ + abort (); \ + fprintf (FILE, "%s", RP); \ + switch ((CODE == 'w' ? 2 \ + : CODE == 'b' ? 1 \ + : CODE == 'k' ? 4 \ + : CODE == 'y' ? 3 \ + : CODE == 'h' ? 0 \ + : GET_MODE_SIZE (GET_MODE (X)))) \ + { \ + case 3: \ + if (STACK_TOP_P (X)) \ + { \ + fputs ("st(0)", FILE); \ + break; \ + } \ + case 4: \ + case 8: \ + case 12: \ + if (! FP_REG_P (X)) fputs ("e", FILE); \ + case 2: \ + fputs (hi_reg_name[REGNO (X)], FILE); \ + break; \ + case 1: \ + fputs (qi_reg_name[REGNO (X)], FILE); \ + break; \ + case 0: \ + fputs (qi_high_reg_name[REGNO (X)], FILE); \ + break; \ + } \ + } while (0) + +#define PRINT_OPERAND(FILE, X, CODE) \ + print_operand (FILE, X, CODE) + +#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \ + print_operand_address (FILE, ADDR) + +/* Print the name of a register for based on its machine mode and number. + This macro is used to print debugging output. + This macro is different from PRINT_REG in that it may be used in + programs that are not linked with aux-output.o. */ + +#define DEBUG_PRINT_REG(X, CODE, FILE) \ + do { static char *hi_name[] = HI_REGISTER_NAMES; \ + static char *qi_name[] = QI_REGISTER_NAMES; \ + fprintf (FILE, "%d %s", REGNO (X), RP); \ + if (REGNO (X) == ARG_POINTER_REGNUM) \ + { fputs ("argp", FILE); break; } \ + if (STACK_TOP_P (X)) \ + { fputs ("st(0)", FILE); break; } \ + if (FP_REG_P (X)) \ + { fputs (hi_name[REGNO(X)], FILE); break; } \ + switch (GET_MODE_SIZE (GET_MODE (X))) \ + { \ + default: \ + fputs ("e", FILE); \ + case 2: \ + fputs (hi_name[REGNO (X)], FILE); \ + break; \ + case 1: \ + fputs (qi_name[REGNO (X)], FILE); \ + break; \ + } \ + } while (0) + +/* Output the prefix for an immediate operand, or for an offset operand. */ +#define PRINT_IMMED_PREFIX(FILE) fputs (IP, (FILE)) +#define PRINT_OFFSET_PREFIX(FILE) fputs (IP, (FILE)) + +/* Routines in libgcc that return floats must return them in an fp reg, + just as other functions do which return such values. + These macros make that happen. */ + +#define FLOAT_VALUE_TYPE float +#define INTIFY(FLOATVAL) FLOATVAL + +/* Nonzero if INSN magically clobbers register REGNO. */ + +/* #define INSN_CLOBBERS_REGNO_P(INSN, REGNO) \ + (FP_REGNO_P (REGNO) \ + && (GET_CODE (INSN) == JUMP_INSN || GET_CODE (INSN) == BARRIER)) +*/ + +/* a letter which is not needed by the normal asm syntax, which + we can use for operand syntax in the extended asm */ + +#define ASM_OPERAND_LETTER '#' + +#define RET return "" +#define AT_SP(mode) (gen_rtx (MEM, (mode), stack_pointer_rtx)) + +/* +Local variables: +version-control: t +End: +*/ diff --git a/gnu/usr.bin/cc/include/i386/perform.h b/gnu/usr.bin/cc/include/i386/perform.h new file mode 100644 index 0000000..4fdd7b3 --- /dev/null +++ b/gnu/usr.bin/cc/include/i386/perform.h @@ -0,0 +1,97 @@ +/* Definitions for AT&T assembler syntax for the Intel 80386. + Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Defines to be able to build libgcc.a with GCC. */ + +/* It might seem that these are not important, since gcc 2 will never + call libgcc for these functions. But programs might be linked with + code compiled by gcc 1, and then these will be used. */ + +/* The arg names used to be a and b, but `a' appears inside strings + and that confuses non-ANSI cpp. */ + +#define perform_udivsi3(arg0,arg1) \ +{ \ + register int dx asm("dx"); \ + register int ax asm("ax"); \ + \ + dx = 0; \ + ax = arg0; \ + asm ("divl %3" : "=a" (ax), "=d" (dx) : "a" (ax), "g" (arg1), "d" (dx)); \ + return ax; \ +} + +#define perform_divsi3(arg0,arg1) \ +{ \ + register int dx asm("dx"); \ + register int ax asm("ax"); \ + register int cx asm("cx"); \ + \ + ax = arg0; \ + cx = arg1; \ + asm ("cltd\n\tidivl %3" : "=a" (ax), "=&d" (dx) : "a" (ax), "c" (cx)); \ + return ax; \ +} + +#define perform_umodsi3(arg0,arg1) \ +{ \ + register int dx asm("dx"); \ + register int ax asm("ax"); \ + \ + dx = 0; \ + ax = arg0; \ + asm ("divl %3" : "=a" (ax), "=d" (dx) : "a" (ax), "g" (arg1), "d" (dx)); \ + return dx; \ +} + +#define perform_modsi3(arg0,arg1) \ +{ \ + register int dx asm("dx"); \ + register int ax asm("ax"); \ + register int cx asm("cx"); \ + \ + ax = arg0; \ + cx = arg1; \ + asm ("cltd\n\tidivl %3" : "=a" (ax), "=&d" (dx) : "a" (ax), "c" (cx)); \ + return dx; \ +} + +#define perform_fixdfsi(arg0) \ +{ \ + auto unsigned short ostatus; \ + auto unsigned short nstatus; \ + auto int ret; \ + auto double tmp; \ + \ + &ostatus; /* guarantee these land in memory */ \ + &nstatus; \ + &ret; \ + &tmp; \ + \ + asm volatile ("fnstcw %0" : "=m" (ostatus)); \ + nstatus = ostatus | 0x0c00; \ + asm volatile ("fldcw %0" : /* no outputs */ : "m" (nstatus)); \ + tmp = arg0; \ + asm volatile ("fldl %0" : /* no outputs */ : "m" (tmp)); \ + asm volatile ("fistpl %0" : "=m" (ret)); \ + asm volatile ("fldcw %0" : /* no outputs */ : "m" (ostatus)); \ + \ + return ret; \ +} + diff --git a/gnu/usr.bin/cc/include/i386/unix.h b/gnu/usr.bin/cc/include/i386/unix.h new file mode 100644 index 0000000..7209176 --- /dev/null +++ b/gnu/usr.bin/cc/include/i386/unix.h @@ -0,0 +1,145 @@ +/* Definitions for Unix assembler syntax for the Intel 80386. + Copyright (C) 1988 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This file defines the aspects of assembler syntax + that are the same for all the i386 Unix systems + (though they may differ in non-Unix systems). */ + +/* Define some concatenation macros to concatenate an opcode + and one, two or three operands. In other assembler syntaxes + they may alter the order of ther operands. */ + +/* Note that the other files fail to use these + in some of the places where they should. */ + +#ifdef __STDC__ +#define AS2(a,b,c) #a " " #b "," #c +#define AS3(a,b,c,d) #a " " #b "," #c "," #d +#define AS1(a,b) #a " " #b +#else +#define AS1(a,b) "a b" +#define AS2(a,b,c) "a b,c" +#define AS3(a,b,c,d) "a b,c,d" +#endif + +/* Define macro used to output shift-double opcodes when the shift + count is in %cl. Some assemblers require %cl as an argument; + some don't. This macro controls what to do: by default, don't + print %cl. */ +#define AS3_SHIFT_DOUBLE(a,b,c,d) AS2 (a,c,d) + +/* Output the size-letter for an opcode. + CODE is the letter used in an operand spec (L, B, W, S or Q). + CH is the corresponding lower case letter + (except if CODE is `Q' then CH is `l', unless GAS_MNEMONICS). */ +#define PUT_OP_SIZE(CODE,CH,FILE) putc (CH,(FILE)) + +/* Opcode suffix for fullword insn. */ +#define L_SIZE "l" + +/* Prefix for register names in this syntax. */ +#define RP "%" + +/* Prefix for immediate operands in this syntax. */ +#define IP "$" + +/* Indirect call instructions should use `*'. */ +#define USE_STAR 1 + +/* Prefix for a memory-operand X. */ +#define PRINT_PTR(X, FILE) + +/* Delimiters that surround base reg and index reg. */ +#define ADDR_BEG(FILE) putc('(', (FILE)) +#define ADDR_END(FILE) putc(')', (FILE)) + +/* Print an index register (whose rtx is IREG). */ +#define PRINT_IREG(FILE,IREG) \ + do \ + { fputs (",", (FILE)); PRINT_REG ((IREG), 0, (FILE)); } \ + while (0) + +/* Print an index scale factor SCALE. */ +#define PRINT_SCALE(FILE,SCALE) \ + if ((SCALE) != 1) fprintf ((FILE), ",%d", (SCALE)) + +/* Print a base/index combination. + BREG is the base reg rtx, IREG is the index reg rtx, + and SCALE is the index scale factor (an integer). */ + +#define PRINT_B_I_S(BREG,IREG,SCALE,FILE) \ + { ADDR_BEG (FILE); \ + if (BREG) PRINT_REG ((BREG), 0, (FILE)); \ + if ((IREG) != 0) \ + { PRINT_IREG ((FILE), (IREG)); \ + PRINT_SCALE ((FILE), (SCALE)); } \ + ADDR_END (FILE); } + +/* Define the syntax of pseudo-ops, labels and comments. */ + +/* String containing the assembler's comment-starter. */ + +#define ASM_COMMENT_START "/" +#define COMMENT_BEGIN "/" + +/* Output to assembler file text saying following lines + may contain character constants, extra white space, comments, etc. */ + +#define ASM_APP_ON "/APP\n" + +/* Output to assembler file text saying following lines + no longer contain unusual constructs. */ + +#define ASM_APP_OFF "/NO_APP\n" + +/* Output before read-only data. */ + +#define TEXT_SECTION_ASM_OP ".text" + +/* Output before writable (initialized) data. */ + +#define DATA_SECTION_ASM_OP ".data" + +/* Output before writable (uninitialized) data. */ + +#define BSS_SECTION_ASM_OP ".bss" + +/* This is how to output a command to make the user-level label named NAME + defined for reference from other files. */ + +#define ASM_GLOBALIZE_LABEL(FILE,NAME) \ + (fputs (".globl ", FILE), assemble_name (FILE, NAME), fputs ("\n", FILE)) + +/* By default, target has a 80387, uses IEEE compatible arithmetic, + and returns float values in the 387, ie, + (TARGET_80387 | TARGET_IEEE_FP | TARGET_FLOAT_RETURNS_IN_80387) */ + +#define TARGET_DEFAULT 0301 + +/* Floating-point return values come in the FP register. */ + +#define VALUE_REGNO(MODE) \ + (GET_MODE_CLASS (MODE) == MODE_FLOAT \ + && TARGET_FLOAT_RETURNS_IN_80387 ? FIRST_FLOAT_REG : 0) + +/* 1 if N is a possible register number for a function value. */ + +#define FUNCTION_VALUE_REGNO_P(N) \ + ((N) == 0 || ((N)== FIRST_FLOAT_REG && TARGET_FLOAT_RETURNS_IN_80387)) + diff --git a/gnu/usr.bin/cc/include/input.h b/gnu/usr.bin/cc/include/input.h new file mode 100644 index 0000000..39590e2 --- /dev/null +++ b/gnu/usr.bin/cc/include/input.h @@ -0,0 +1,46 @@ +/* Declarations for variables relating to reading the source file. + Used by parsers, lexical analyzers, and error message routines. + + Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Source file current line is coming from. */ +extern char *input_filename; + +/* Top-level source file. */ +extern char *main_input_filename; + +/* Line number in current source file. */ +extern int lineno; + +/* Stream for reading from input file. */ +extern FILE *finput; + +struct file_stack + { + char *name; + struct file_stack *next; + int line; + }; + +/* Stack of currently pending input files. + The line member is not accurate for the innermost file on the stack. */ +extern struct file_stack *input_file_stack; + +/* Incremented on each change to input_file_stack. */ +extern int input_file_stack_tick; diff --git a/gnu/usr.bin/cc/include/insn-attr.h b/gnu/usr.bin/cc/include/insn-attr.h new file mode 100644 index 0000000..5fe9a2f --- /dev/null +++ b/gnu/usr.bin/cc/include/insn-attr.h @@ -0,0 +1,19 @@ +/* Generated automatically by the program `genattr' +from the machine description file `md'. */ + +#ifndef PROTO +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define PROTO(ARGS) ARGS +#else +#define PROTO(ARGS) () +#endif +#endif +#define HAVE_ATTR_alternative +#define get_attr_alternative(insn) which_alternative + +#define ATTR_FLAG_forward 0x1 +#define ATTR_FLAG_backward 0x2 +#define ATTR_FLAG_likely 0x4 +#define ATTR_FLAG_very_likely 0x8 +#define ATTR_FLAG_unlikely 0x10 +#define ATTR_FLAG_very_unlikely 0x20 diff --git a/gnu/usr.bin/cc/include/insn-codes.h b/gnu/usr.bin/cc/include/insn-codes.h new file mode 100644 index 0000000..59e24c9 --- /dev/null +++ b/gnu/usr.bin/cc/include/insn-codes.h @@ -0,0 +1,201 @@ +/* Generated automatically by the program `gencodes' +from the machine description file `md'. */ + +#ifndef MAX_INSN_CODE + +enum insn_code { + CODE_FOR_tstsi_1 = 0, + CODE_FOR_tstsi = 1, + CODE_FOR_tsthi_1 = 2, + CODE_FOR_tsthi = 3, + CODE_FOR_tstqi_1 = 4, + CODE_FOR_tstqi = 5, + CODE_FOR_tstsf_cc = 6, + CODE_FOR_tstsf = 7, + CODE_FOR_tstdf_cc = 8, + CODE_FOR_tstdf = 9, + CODE_FOR_tstxf_cc = 10, + CODE_FOR_tstxf = 11, + CODE_FOR_cmpsi_1 = 12, + CODE_FOR_cmpsi = 13, + CODE_FOR_cmphi_1 = 14, + CODE_FOR_cmphi = 15, + CODE_FOR_cmpqi_1 = 16, + CODE_FOR_cmpqi = 17, + CODE_FOR_cmpsf_cc_1 = 30, + CODE_FOR_cmpxf = 34, + CODE_FOR_cmpdf = 35, + CODE_FOR_cmpsf = 36, + CODE_FOR_cmpxf_cc = 37, + CODE_FOR_cmpxf_ccfpeq = 38, + CODE_FOR_cmpdf_cc = 39, + CODE_FOR_cmpdf_ccfpeq = 40, + CODE_FOR_cmpsf_cc = 41, + CODE_FOR_cmpsf_ccfpeq = 42, + CODE_FOR_movsi = 48, + CODE_FOR_movhi = 51, + CODE_FOR_movstricthi = 52, + CODE_FOR_movqi = 54, + CODE_FOR_movstrictqi = 55, + CODE_FOR_movsf = 57, + CODE_FOR_swapdf = 59, + CODE_FOR_movdf = 60, + CODE_FOR_swapxf = 62, + CODE_FOR_movxf = 63, + CODE_FOR_movdi = 65, + CODE_FOR_zero_extendhisi2 = 66, + CODE_FOR_zero_extendqihi2 = 67, + CODE_FOR_zero_extendqisi2 = 68, + CODE_FOR_zero_extendsidi2 = 69, + CODE_FOR_extendsidi2 = 70, + CODE_FOR_extendhisi2 = 71, + CODE_FOR_extendqihi2 = 72, + CODE_FOR_extendqisi2 = 73, + CODE_FOR_extendsfdf2 = 74, + CODE_FOR_extenddfxf2 = 75, + CODE_FOR_extendsfxf2 = 76, + CODE_FOR_truncdfsf2 = 77, + CODE_FOR_truncxfsf2 = 79, + CODE_FOR_truncxfdf2 = 80, + CODE_FOR_fixuns_truncxfsi2 = 81, + CODE_FOR_fixuns_truncdfsi2 = 82, + CODE_FOR_fixuns_truncsfsi2 = 83, + CODE_FOR_fix_truncxfdi2 = 84, + CODE_FOR_fix_truncdfdi2 = 85, + CODE_FOR_fix_truncsfdi2 = 86, + CODE_FOR_fix_truncxfsi2 = 90, + CODE_FOR_fix_truncdfsi2 = 91, + CODE_FOR_fix_truncsfsi2 = 92, + CODE_FOR_floatsisf2 = 96, + CODE_FOR_floatdisf2 = 97, + CODE_FOR_floatsidf2 = 98, + CODE_FOR_floatdidf2 = 99, + CODE_FOR_floatsixf2 = 100, + CODE_FOR_floatdixf2 = 101, + CODE_FOR_adddi3 = 108, + CODE_FOR_addsi3 = 109, + CODE_FOR_addhi3 = 110, + CODE_FOR_addqi3 = 111, + CODE_FOR_addxf3 = 113, + CODE_FOR_adddf3 = 114, + CODE_FOR_addsf3 = 115, + CODE_FOR_subdi3 = 116, + CODE_FOR_subsi3 = 117, + CODE_FOR_subhi3 = 118, + CODE_FOR_subqi3 = 119, + CODE_FOR_subxf3 = 120, + CODE_FOR_subdf3 = 121, + CODE_FOR_subsf3 = 122, + CODE_FOR_mulhi3 = 124, + CODE_FOR_mulsi3 = 126, + CODE_FOR_umulqihi3 = 127, + CODE_FOR_mulqihi3 = 128, + CODE_FOR_umulsidi3 = 129, + CODE_FOR_mulsidi3 = 130, + CODE_FOR_mulxf3 = 131, + CODE_FOR_muldf3 = 132, + CODE_FOR_mulsf3 = 133, + CODE_FOR_divqi3 = 134, + CODE_FOR_udivqi3 = 135, + CODE_FOR_divxf3 = 136, + CODE_FOR_divdf3 = 137, + CODE_FOR_divsf3 = 138, + CODE_FOR_divmodsi4 = 139, + CODE_FOR_divmodhi4 = 140, + CODE_FOR_udivmodsi4 = 141, + CODE_FOR_udivmodhi4 = 142, + CODE_FOR_andsi3 = 143, + CODE_FOR_andhi3 = 144, + CODE_FOR_andqi3 = 145, + CODE_FOR_iorsi3 = 146, + CODE_FOR_iorhi3 = 147, + CODE_FOR_iorqi3 = 148, + CODE_FOR_xorsi3 = 149, + CODE_FOR_xorhi3 = 150, + CODE_FOR_xorqi3 = 151, + CODE_FOR_negdi2 = 152, + CODE_FOR_negsi2 = 153, + CODE_FOR_neghi2 = 154, + CODE_FOR_negqi2 = 155, + CODE_FOR_negsf2 = 156, + CODE_FOR_negdf2 = 157, + CODE_FOR_negxf2 = 159, + CODE_FOR_abssf2 = 161, + CODE_FOR_absdf2 = 162, + CODE_FOR_absxf2 = 164, + CODE_FOR_sqrtsf2 = 166, + CODE_FOR_sqrtdf2 = 167, + CODE_FOR_sqrtxf2 = 169, + CODE_FOR_sindf2 = 172, + CODE_FOR_sinsf2 = 173, + CODE_FOR_cosdf2 = 175, + CODE_FOR_cossf2 = 176, + CODE_FOR_one_cmplsi2 = 178, + CODE_FOR_one_cmplhi2 = 179, + CODE_FOR_one_cmplqi2 = 180, + CODE_FOR_ashldi3 = 181, + CODE_FOR_ashldi3_const_int = 182, + CODE_FOR_ashldi3_non_const_int = 183, + CODE_FOR_ashlsi3 = 184, + CODE_FOR_ashlhi3 = 185, + CODE_FOR_ashlqi3 = 186, + CODE_FOR_ashrdi3 = 187, + CODE_FOR_ashrdi3_const_int = 188, + CODE_FOR_ashrdi3_non_const_int = 189, + CODE_FOR_ashrsi3 = 190, + CODE_FOR_ashrhi3 = 191, + CODE_FOR_ashrqi3 = 192, + CODE_FOR_lshrdi3 = 193, + CODE_FOR_lshrdi3_const_int = 194, + CODE_FOR_lshrdi3_non_const_int = 195, + CODE_FOR_lshrsi3 = 196, + CODE_FOR_lshrhi3 = 197, + CODE_FOR_lshrqi3 = 198, + CODE_FOR_rotlsi3 = 199, + CODE_FOR_rotlhi3 = 200, + CODE_FOR_rotlqi3 = 201, + CODE_FOR_rotrsi3 = 202, + CODE_FOR_rotrhi3 = 203, + CODE_FOR_rotrqi3 = 204, + CODE_FOR_seq = 211, + CODE_FOR_sne = 213, + CODE_FOR_sgt = 215, + CODE_FOR_sgtu = 217, + CODE_FOR_slt = 219, + CODE_FOR_sltu = 221, + CODE_FOR_sge = 223, + CODE_FOR_sgeu = 225, + CODE_FOR_sle = 227, + CODE_FOR_sleu = 229, + CODE_FOR_beq = 231, + CODE_FOR_bne = 233, + CODE_FOR_bgt = 235, + CODE_FOR_bgtu = 237, + CODE_FOR_blt = 239, + CODE_FOR_bltu = 241, + CODE_FOR_bge = 243, + CODE_FOR_bgeu = 245, + CODE_FOR_ble = 247, + CODE_FOR_bleu = 249, + CODE_FOR_jump = 261, + CODE_FOR_indirect_jump = 262, + CODE_FOR_casesi = 263, + CODE_FOR_tablejump = 265, + CODE_FOR_call_pop = 266, + CODE_FOR_call = 269, + CODE_FOR_call_value_pop = 272, + CODE_FOR_call_value = 275, + CODE_FOR_untyped_call = 278, + CODE_FOR_untyped_return = 281, + CODE_FOR_update_return = 282, + CODE_FOR_return = 283, + CODE_FOR_nop = 284, + CODE_FOR_movstrsi = 285, + CODE_FOR_cmpstrsi = 287, + CODE_FOR_ffssi2 = 290, + CODE_FOR_ffshi2 = 292, + CODE_FOR_strlensi = 307, + CODE_FOR_nothing }; + +#define MAX_INSN_CODE ((int) CODE_FOR_nothing) +#endif /* MAX_INSN_CODE */ diff --git a/gnu/usr.bin/cc/include/insn-config.h b/gnu/usr.bin/cc/include/insn-config.h new file mode 100644 index 0000000..7dba886 --- /dev/null +++ b/gnu/usr.bin/cc/include/insn-config.h @@ -0,0 +1,12 @@ +/* Generated automatically by the program `genconfig' +from the machine description file `md'. */ + + +#define MAX_RECOG_OPERANDS 10 + +#define MAX_DUP_OPERANDS 3 +#ifndef MAX_INSNS_PER_SPLIT +#define MAX_INSNS_PER_SPLIT 1 +#endif +#define REGISTER_CONSTRAINTS +#define HAVE_cc0 diff --git a/gnu/usr.bin/cc/include/insn-flags.h b/gnu/usr.bin/cc/include/insn-flags.h new file mode 100644 index 0000000..c9dd771 --- /dev/null +++ b/gnu/usr.bin/cc/include/insn-flags.h @@ -0,0 +1,598 @@ +/* Generated automatically by the program `genflags' +from the machine description file `md'. */ + +#define HAVE_tstsi_1 1 +#define HAVE_tstsi 1 +#define HAVE_tsthi_1 1 +#define HAVE_tsthi 1 +#define HAVE_tstqi_1 1 +#define HAVE_tstqi 1 +#define HAVE_tstsf_cc (TARGET_80387 && ! TARGET_IEEE_FP) +#define HAVE_tstsf (TARGET_80387 && ! TARGET_IEEE_FP) +#define HAVE_tstdf_cc (TARGET_80387 && ! TARGET_IEEE_FP) +#define HAVE_tstdf (TARGET_80387 && ! TARGET_IEEE_FP) +#define HAVE_tstxf_cc (TARGET_80387 && ! TARGET_IEEE_FP) +#define HAVE_tstxf (TARGET_80387 && ! TARGET_IEEE_FP) +#define HAVE_cmpsi_1 (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) +#define HAVE_cmpsi 1 +#define HAVE_cmphi_1 (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) +#define HAVE_cmphi 1 +#define HAVE_cmpqi_1 (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) +#define HAVE_cmpqi 1 +#define HAVE_cmpsf_cc_1 (TARGET_80387 \ + && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)) +#define HAVE_cmpxf (TARGET_80387) +#define HAVE_cmpdf (TARGET_80387) +#define HAVE_cmpsf (TARGET_80387) +#define HAVE_cmpxf_cc (TARGET_80387) +#define HAVE_cmpxf_ccfpeq (TARGET_80387) +#define HAVE_cmpdf_cc (TARGET_80387) +#define HAVE_cmpdf_ccfpeq (TARGET_80387) +#define HAVE_cmpsf_cc (TARGET_80387) +#define HAVE_cmpsf_ccfpeq (TARGET_80387) +#define HAVE_movsi 1 +#define HAVE_movhi 1 +#define HAVE_movstricthi 1 +#define HAVE_movqi 1 +#define HAVE_movstrictqi 1 +#define HAVE_movsf 1 +#define HAVE_swapdf 1 +#define HAVE_movdf 1 +#define HAVE_swapxf 1 +#define HAVE_movxf 1 +#define HAVE_movdi 1 +#define HAVE_zero_extendhisi2 1 +#define HAVE_zero_extendqihi2 1 +#define HAVE_zero_extendqisi2 1 +#define HAVE_zero_extendsidi2 1 +#define HAVE_extendsidi2 1 +#define HAVE_extendhisi2 1 +#define HAVE_extendqihi2 1 +#define HAVE_extendqisi2 1 +#define HAVE_extendsfdf2 (TARGET_80387) +#define HAVE_extenddfxf2 (TARGET_80387) +#define HAVE_extendsfxf2 (TARGET_80387) +#define HAVE_truncdfsf2 (TARGET_80387) +#define HAVE_truncxfsf2 (TARGET_80387) +#define HAVE_truncxfdf2 (TARGET_80387) +#define HAVE_fixuns_truncxfsi2 (TARGET_80387) +#define HAVE_fixuns_truncdfsi2 (TARGET_80387) +#define HAVE_fixuns_truncsfsi2 (TARGET_80387) +#define HAVE_fix_truncxfdi2 (TARGET_80387) +#define HAVE_fix_truncdfdi2 (TARGET_80387) +#define HAVE_fix_truncsfdi2 (TARGET_80387) +#define HAVE_fix_truncxfsi2 (TARGET_80387) +#define HAVE_fix_truncdfsi2 (TARGET_80387) +#define HAVE_fix_truncsfsi2 (TARGET_80387) +#define HAVE_floatsisf2 (TARGET_80387) +#define HAVE_floatdisf2 (TARGET_80387) +#define HAVE_floatsidf2 (TARGET_80387) +#define HAVE_floatdidf2 (TARGET_80387) +#define HAVE_floatsixf2 (TARGET_80387) +#define HAVE_floatdixf2 (TARGET_80387) +#define HAVE_adddi3 1 +#define HAVE_addsi3 1 +#define HAVE_addhi3 1 +#define HAVE_addqi3 1 +#define HAVE_addxf3 (TARGET_80387) +#define HAVE_adddf3 (TARGET_80387) +#define HAVE_addsf3 (TARGET_80387) +#define HAVE_subdi3 1 +#define HAVE_subsi3 1 +#define HAVE_subhi3 1 +#define HAVE_subqi3 1 +#define HAVE_subxf3 (TARGET_80387) +#define HAVE_subdf3 (TARGET_80387) +#define HAVE_subsf3 (TARGET_80387) +#define HAVE_mulhi3 1 +#define HAVE_mulsi3 1 +#define HAVE_umulqihi3 1 +#define HAVE_mulqihi3 1 +#define HAVE_umulsidi3 1 +#define HAVE_mulsidi3 1 +#define HAVE_mulxf3 (TARGET_80387) +#define HAVE_muldf3 (TARGET_80387) +#define HAVE_mulsf3 (TARGET_80387) +#define HAVE_divqi3 1 +#define HAVE_udivqi3 1 +#define HAVE_divxf3 (TARGET_80387) +#define HAVE_divdf3 (TARGET_80387) +#define HAVE_divsf3 (TARGET_80387) +#define HAVE_divmodsi4 1 +#define HAVE_divmodhi4 1 +#define HAVE_udivmodsi4 1 +#define HAVE_udivmodhi4 1 +#define HAVE_andsi3 1 +#define HAVE_andhi3 1 +#define HAVE_andqi3 1 +#define HAVE_iorsi3 1 +#define HAVE_iorhi3 1 +#define HAVE_iorqi3 1 +#define HAVE_xorsi3 1 +#define HAVE_xorhi3 1 +#define HAVE_xorqi3 1 +#define HAVE_negdi2 1 +#define HAVE_negsi2 1 +#define HAVE_neghi2 1 +#define HAVE_negqi2 1 +#define HAVE_negsf2 (TARGET_80387) +#define HAVE_negdf2 (TARGET_80387) +#define HAVE_negxf2 (TARGET_80387) +#define HAVE_abssf2 (TARGET_80387) +#define HAVE_absdf2 (TARGET_80387) +#define HAVE_absxf2 (TARGET_80387) +#define HAVE_sqrtsf2 (! TARGET_NO_FANCY_MATH_387 && TARGET_80387 \ + && (TARGET_IEEE_FP || flag_fast_math) ) +#define HAVE_sqrtdf2 (! TARGET_NO_FANCY_MATH_387 && TARGET_80387 \ + && (TARGET_IEEE_FP || flag_fast_math) ) +#define HAVE_sqrtxf2 (! TARGET_NO_FANCY_MATH_387 && TARGET_80387 \ + && (TARGET_IEEE_FP || flag_fast_math) ) +#define HAVE_sindf2 (! TARGET_NO_FANCY_MATH_387 && TARGET_80387 \ + && (TARGET_IEEE_FP || flag_fast_math) ) +#define HAVE_sinsf2 (! TARGET_NO_FANCY_MATH_387 && TARGET_80387 \ + && (TARGET_IEEE_FP || flag_fast_math) ) +#define HAVE_cosdf2 (! TARGET_NO_FANCY_MATH_387 && TARGET_80387 \ + && (TARGET_IEEE_FP || flag_fast_math) ) +#define HAVE_cossf2 (! TARGET_NO_FANCY_MATH_387 && TARGET_80387 \ + && (TARGET_IEEE_FP || flag_fast_math) ) +#define HAVE_one_cmplsi2 1 +#define HAVE_one_cmplhi2 1 +#define HAVE_one_cmplqi2 1 +#define HAVE_ashldi3 1 +#define HAVE_ashldi3_const_int 1 +#define HAVE_ashldi3_non_const_int 1 +#define HAVE_ashlsi3 1 +#define HAVE_ashlhi3 1 +#define HAVE_ashlqi3 1 +#define HAVE_ashrdi3 1 +#define HAVE_ashrdi3_const_int 1 +#define HAVE_ashrdi3_non_const_int 1 +#define HAVE_ashrsi3 1 +#define HAVE_ashrhi3 1 +#define HAVE_ashrqi3 1 +#define HAVE_lshrdi3 1 +#define HAVE_lshrdi3_const_int 1 +#define HAVE_lshrdi3_non_const_int 1 +#define HAVE_lshrsi3 1 +#define HAVE_lshrhi3 1 +#define HAVE_lshrqi3 1 +#define HAVE_rotlsi3 1 +#define HAVE_rotlhi3 1 +#define HAVE_rotlqi3 1 +#define HAVE_rotrsi3 1 +#define HAVE_rotrhi3 1 +#define HAVE_rotrqi3 1 +#define HAVE_seq 1 +#define HAVE_sne 1 +#define HAVE_sgt 1 +#define HAVE_sgtu 1 +#define HAVE_slt 1 +#define HAVE_sltu 1 +#define HAVE_sge 1 +#define HAVE_sgeu 1 +#define HAVE_sle 1 +#define HAVE_sleu 1 +#define HAVE_beq 1 +#define HAVE_bne 1 +#define HAVE_bgt 1 +#define HAVE_bgtu 1 +#define HAVE_blt 1 +#define HAVE_bltu 1 +#define HAVE_bge 1 +#define HAVE_bgeu 1 +#define HAVE_ble 1 +#define HAVE_bleu 1 +#define HAVE_jump 1 +#define HAVE_indirect_jump 1 +#define HAVE_casesi (flag_pic) +#define HAVE_tablejump 1 +#define HAVE_call_pop 1 +#define HAVE_call 1 +#define HAVE_call_value_pop 1 +#define HAVE_call_value 1 +#define HAVE_untyped_call 1 +#define HAVE_untyped_return 1 +#define HAVE_update_return 1 +#define HAVE_return (simple_386_epilogue ()) +#define HAVE_nop 1 +#define HAVE_movstrsi 1 +#define HAVE_cmpstrsi 1 +#define HAVE_ffssi2 1 +#define HAVE_ffshi2 1 +#define HAVE_strlensi 1 + +#ifndef NO_MD_PROTOTYPES +extern rtx gen_tstsi_1 PROTO((rtx)); +extern rtx gen_tstsi PROTO((rtx)); +extern rtx gen_tsthi_1 PROTO((rtx)); +extern rtx gen_tsthi PROTO((rtx)); +extern rtx gen_tstqi_1 PROTO((rtx)); +extern rtx gen_tstqi PROTO((rtx)); +extern rtx gen_tstsf_cc PROTO((rtx)); +extern rtx gen_tstsf PROTO((rtx)); +extern rtx gen_tstdf_cc PROTO((rtx)); +extern rtx gen_tstdf PROTO((rtx)); +extern rtx gen_tstxf_cc PROTO((rtx)); +extern rtx gen_tstxf PROTO((rtx)); +extern rtx gen_cmpsi_1 PROTO((rtx, rtx)); +extern rtx gen_cmpsi PROTO((rtx, rtx)); +extern rtx gen_cmphi_1 PROTO((rtx, rtx)); +extern rtx gen_cmphi PROTO((rtx, rtx)); +extern rtx gen_cmpqi_1 PROTO((rtx, rtx)); +extern rtx gen_cmpqi PROTO((rtx, rtx)); +extern rtx gen_cmpsf_cc_1 PROTO((rtx, rtx, rtx)); +extern rtx gen_cmpxf PROTO((rtx, rtx)); +extern rtx gen_cmpdf PROTO((rtx, rtx)); +extern rtx gen_cmpsf PROTO((rtx, rtx)); +extern rtx gen_cmpxf_cc PROTO((rtx, rtx)); +extern rtx gen_cmpxf_ccfpeq PROTO((rtx, rtx)); +extern rtx gen_cmpdf_cc PROTO((rtx, rtx)); +extern rtx gen_cmpdf_ccfpeq PROTO((rtx, rtx)); +extern rtx gen_cmpsf_cc PROTO((rtx, rtx)); +extern rtx gen_cmpsf_ccfpeq PROTO((rtx, rtx)); +extern rtx gen_movsi PROTO((rtx, rtx)); +extern rtx gen_movhi PROTO((rtx, rtx)); +extern rtx gen_movstricthi PROTO((rtx, rtx)); +extern rtx gen_movqi PROTO((rtx, rtx)); +extern rtx gen_movstrictqi PROTO((rtx, rtx)); +extern rtx gen_movsf PROTO((rtx, rtx)); +extern rtx gen_swapdf PROTO((rtx, rtx)); +extern rtx gen_movdf PROTO((rtx, rtx)); +extern rtx gen_swapxf PROTO((rtx, rtx)); +extern rtx gen_movxf PROTO((rtx, rtx)); +extern rtx gen_movdi PROTO((rtx, rtx)); +extern rtx gen_zero_extendhisi2 PROTO((rtx, rtx)); +extern rtx gen_zero_extendqihi2 PROTO((rtx, rtx)); +extern rtx gen_zero_extendqisi2 PROTO((rtx, rtx)); +extern rtx gen_zero_extendsidi2 PROTO((rtx, rtx)); +extern rtx gen_extendsidi2 PROTO((rtx, rtx)); +extern rtx gen_extendhisi2 PROTO((rtx, rtx)); +extern rtx gen_extendqihi2 PROTO((rtx, rtx)); +extern rtx gen_extendqisi2 PROTO((rtx, rtx)); +extern rtx gen_extendsfdf2 PROTO((rtx, rtx)); +extern rtx gen_extenddfxf2 PROTO((rtx, rtx)); +extern rtx gen_extendsfxf2 PROTO((rtx, rtx)); +extern rtx gen_truncdfsf2 PROTO((rtx, rtx)); +extern rtx gen_truncxfsf2 PROTO((rtx, rtx)); +extern rtx gen_truncxfdf2 PROTO((rtx, rtx)); +extern rtx gen_fixuns_truncxfsi2 PROTO((rtx, rtx)); +extern rtx gen_fixuns_truncdfsi2 PROTO((rtx, rtx)); +extern rtx gen_fixuns_truncsfsi2 PROTO((rtx, rtx)); +extern rtx gen_fix_truncxfdi2 PROTO((rtx, rtx)); +extern rtx gen_fix_truncdfdi2 PROTO((rtx, rtx)); +extern rtx gen_fix_truncsfdi2 PROTO((rtx, rtx)); +extern rtx gen_fix_truncxfsi2 PROTO((rtx, rtx)); +extern rtx gen_fix_truncdfsi2 PROTO((rtx, rtx)); +extern rtx gen_fix_truncsfsi2 PROTO((rtx, rtx)); +extern rtx gen_floatsisf2 PROTO((rtx, rtx)); +extern rtx gen_floatdisf2 PROTO((rtx, rtx)); +extern rtx gen_floatsidf2 PROTO((rtx, rtx)); +extern rtx gen_floatdidf2 PROTO((rtx, rtx)); +extern rtx gen_floatsixf2 PROTO((rtx, rtx)); +extern rtx gen_floatdixf2 PROTO((rtx, rtx)); +extern rtx gen_adddi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_addsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_addhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_addqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_addxf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_adddf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_addsf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_subdi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_subsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_subhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_subqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_subxf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_subdf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_subsf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_mulhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_mulsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_umulqihi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_mulqihi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_umulsidi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_mulsidi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_mulxf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_muldf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_mulsf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_divqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_udivqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_divxf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_divdf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_divsf3 PROTO((rtx, rtx, rtx)); +extern rtx gen_divmodsi4 PROTO((rtx, rtx, rtx, rtx)); +extern rtx gen_divmodhi4 PROTO((rtx, rtx, rtx, rtx)); +extern rtx gen_udivmodsi4 PROTO((rtx, rtx, rtx, rtx)); +extern rtx gen_udivmodhi4 PROTO((rtx, rtx, rtx, rtx)); +extern rtx gen_andsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_andhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_andqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_iorsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_iorhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_iorqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_xorsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_xorhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_xorqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_negdi2 PROTO((rtx, rtx)); +extern rtx gen_negsi2 PROTO((rtx, rtx)); +extern rtx gen_neghi2 PROTO((rtx, rtx)); +extern rtx gen_negqi2 PROTO((rtx, rtx)); +extern rtx gen_negsf2 PROTO((rtx, rtx)); +extern rtx gen_negdf2 PROTO((rtx, rtx)); +extern rtx gen_negxf2 PROTO((rtx, rtx)); +extern rtx gen_abssf2 PROTO((rtx, rtx)); +extern rtx gen_absdf2 PROTO((rtx, rtx)); +extern rtx gen_absxf2 PROTO((rtx, rtx)); +extern rtx gen_sqrtsf2 PROTO((rtx, rtx)); +extern rtx gen_sqrtdf2 PROTO((rtx, rtx)); +extern rtx gen_sqrtxf2 PROTO((rtx, rtx)); +extern rtx gen_sindf2 PROTO((rtx, rtx)); +extern rtx gen_sinsf2 PROTO((rtx, rtx)); +extern rtx gen_cosdf2 PROTO((rtx, rtx)); +extern rtx gen_cossf2 PROTO((rtx, rtx)); +extern rtx gen_one_cmplsi2 PROTO((rtx, rtx)); +extern rtx gen_one_cmplhi2 PROTO((rtx, rtx)); +extern rtx gen_one_cmplqi2 PROTO((rtx, rtx)); +extern rtx gen_ashldi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_ashldi3_const_int PROTO((rtx, rtx, rtx)); +extern rtx gen_ashldi3_non_const_int PROTO((rtx, rtx, rtx)); +extern rtx gen_ashlsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_ashlhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_ashlqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_ashrdi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_ashrdi3_const_int PROTO((rtx, rtx, rtx)); +extern rtx gen_ashrdi3_non_const_int PROTO((rtx, rtx, rtx)); +extern rtx gen_ashrsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_ashrhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_ashrqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_lshrdi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_lshrdi3_const_int PROTO((rtx, rtx, rtx)); +extern rtx gen_lshrdi3_non_const_int PROTO((rtx, rtx, rtx)); +extern rtx gen_lshrsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_lshrhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_lshrqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_rotlsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_rotlhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_rotlqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_rotrsi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_rotrhi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_rotrqi3 PROTO((rtx, rtx, rtx)); +extern rtx gen_seq PROTO((rtx)); +extern rtx gen_sne PROTO((rtx)); +extern rtx gen_sgt PROTO((rtx)); +extern rtx gen_sgtu PROTO((rtx)); +extern rtx gen_slt PROTO((rtx)); +extern rtx gen_sltu PROTO((rtx)); +extern rtx gen_sge PROTO((rtx)); +extern rtx gen_sgeu PROTO((rtx)); +extern rtx gen_sle PROTO((rtx)); +extern rtx gen_sleu PROTO((rtx)); +extern rtx gen_beq PROTO((rtx)); +extern rtx gen_bne PROTO((rtx)); +extern rtx gen_bgt PROTO((rtx)); +extern rtx gen_bgtu PROTO((rtx)); +extern rtx gen_blt PROTO((rtx)); +extern rtx gen_bltu PROTO((rtx)); +extern rtx gen_bge PROTO((rtx)); +extern rtx gen_bgeu PROTO((rtx)); +extern rtx gen_ble PROTO((rtx)); +extern rtx gen_bleu PROTO((rtx)); +extern rtx gen_jump PROTO((rtx)); +extern rtx gen_indirect_jump PROTO((rtx)); +extern rtx gen_casesi PROTO((rtx, rtx, rtx, rtx, rtx)); +extern rtx gen_tablejump PROTO((rtx, rtx)); +extern rtx gen_untyped_call PROTO((rtx, rtx, rtx)); +extern rtx gen_untyped_return PROTO((rtx, rtx)); +extern rtx gen_update_return PROTO((rtx)); +extern rtx gen_return PROTO((void)); +extern rtx gen_nop PROTO((void)); +extern rtx gen_movstrsi PROTO((rtx, rtx, rtx, rtx)); +extern rtx gen_cmpstrsi PROTO((rtx, rtx, rtx, rtx, rtx)); +extern rtx gen_ffssi2 PROTO((rtx, rtx)); +extern rtx gen_ffshi2 PROTO((rtx, rtx)); +extern rtx gen_strlensi PROTO((rtx, rtx, rtx, rtx)); + +#ifdef MD_CALL_PROTOTYPES +extern rtx gen_call_pop PROTO((rtx, rtx, rtx)); +extern rtx gen_call PROTO((rtx, rtx)); +extern rtx gen_call_value_pop PROTO((rtx, rtx, rtx, rtx)); +extern rtx gen_call_value PROTO((rtx, rtx, rtx)); + +#else /* !MD_CALL_PROTOTYPES */ +extern rtx gen_call_pop (); +extern rtx gen_call (); +extern rtx gen_call_value_pop (); +extern rtx gen_call_value (); +#endif /* !MD_CALL_PROTOTYPES */ + +#else /* NO_MD_PROTOTYPES */ +extern rtx gen_tstsi_1 (); +extern rtx gen_tstsi (); +extern rtx gen_tsthi_1 (); +extern rtx gen_tsthi (); +extern rtx gen_tstqi_1 (); +extern rtx gen_tstqi (); +extern rtx gen_tstsf_cc (); +extern rtx gen_tstsf (); +extern rtx gen_tstdf_cc (); +extern rtx gen_tstdf (); +extern rtx gen_tstxf_cc (); +extern rtx gen_tstxf (); +extern rtx gen_cmpsi_1 (); +extern rtx gen_cmpsi (); +extern rtx gen_cmphi_1 (); +extern rtx gen_cmphi (); +extern rtx gen_cmpqi_1 (); +extern rtx gen_cmpqi (); +extern rtx gen_cmpsf_cc_1 (); +extern rtx gen_cmpxf (); +extern rtx gen_cmpdf (); +extern rtx gen_cmpsf (); +extern rtx gen_cmpxf_cc (); +extern rtx gen_cmpxf_ccfpeq (); +extern rtx gen_cmpdf_cc (); +extern rtx gen_cmpdf_ccfpeq (); +extern rtx gen_cmpsf_cc (); +extern rtx gen_cmpsf_ccfpeq (); +extern rtx gen_movsi (); +extern rtx gen_movhi (); +extern rtx gen_movstricthi (); +extern rtx gen_movqi (); +extern rtx gen_movstrictqi (); +extern rtx gen_movsf (); +extern rtx gen_swapdf (); +extern rtx gen_movdf (); +extern rtx gen_swapxf (); +extern rtx gen_movxf (); +extern rtx gen_movdi (); +extern rtx gen_zero_extendhisi2 (); +extern rtx gen_zero_extendqihi2 (); +extern rtx gen_zero_extendqisi2 (); +extern rtx gen_zero_extendsidi2 (); +extern rtx gen_extendsidi2 (); +extern rtx gen_extendhisi2 (); +extern rtx gen_extendqihi2 (); +extern rtx gen_extendqisi2 (); +extern rtx gen_extendsfdf2 (); +extern rtx gen_extenddfxf2 (); +extern rtx gen_extendsfxf2 (); +extern rtx gen_truncdfsf2 (); +extern rtx gen_truncxfsf2 (); +extern rtx gen_truncxfdf2 (); +extern rtx gen_fixuns_truncxfsi2 (); +extern rtx gen_fixuns_truncdfsi2 (); +extern rtx gen_fixuns_truncsfsi2 (); +extern rtx gen_fix_truncxfdi2 (); +extern rtx gen_fix_truncdfdi2 (); +extern rtx gen_fix_truncsfdi2 (); +extern rtx gen_fix_truncxfsi2 (); +extern rtx gen_fix_truncdfsi2 (); +extern rtx gen_fix_truncsfsi2 (); +extern rtx gen_floatsisf2 (); +extern rtx gen_floatdisf2 (); +extern rtx gen_floatsidf2 (); +extern rtx gen_floatdidf2 (); +extern rtx gen_floatsixf2 (); +extern rtx gen_floatdixf2 (); +extern rtx gen_adddi3 (); +extern rtx gen_addsi3 (); +extern rtx gen_addhi3 (); +extern rtx gen_addqi3 (); +extern rtx gen_addxf3 (); +extern rtx gen_adddf3 (); +extern rtx gen_addsf3 (); +extern rtx gen_subdi3 (); +extern rtx gen_subsi3 (); +extern rtx gen_subhi3 (); +extern rtx gen_subqi3 (); +extern rtx gen_subxf3 (); +extern rtx gen_subdf3 (); +extern rtx gen_subsf3 (); +extern rtx gen_mulhi3 (); +extern rtx gen_mulsi3 (); +extern rtx gen_umulqihi3 (); +extern rtx gen_mulqihi3 (); +extern rtx gen_umulsidi3 (); +extern rtx gen_mulsidi3 (); +extern rtx gen_mulxf3 (); +extern rtx gen_muldf3 (); +extern rtx gen_mulsf3 (); +extern rtx gen_divqi3 (); +extern rtx gen_udivqi3 (); +extern rtx gen_divxf3 (); +extern rtx gen_divdf3 (); +extern rtx gen_divsf3 (); +extern rtx gen_divmodsi4 (); +extern rtx gen_divmodhi4 (); +extern rtx gen_udivmodsi4 (); +extern rtx gen_udivmodhi4 (); +extern rtx gen_andsi3 (); +extern rtx gen_andhi3 (); +extern rtx gen_andqi3 (); +extern rtx gen_iorsi3 (); +extern rtx gen_iorhi3 (); +extern rtx gen_iorqi3 (); +extern rtx gen_xorsi3 (); +extern rtx gen_xorhi3 (); +extern rtx gen_xorqi3 (); +extern rtx gen_negdi2 (); +extern rtx gen_negsi2 (); +extern rtx gen_neghi2 (); +extern rtx gen_negqi2 (); +extern rtx gen_negsf2 (); +extern rtx gen_negdf2 (); +extern rtx gen_negxf2 (); +extern rtx gen_abssf2 (); +extern rtx gen_absdf2 (); +extern rtx gen_absxf2 (); +extern rtx gen_sqrtsf2 (); +extern rtx gen_sqrtdf2 (); +extern rtx gen_sqrtxf2 (); +extern rtx gen_sindf2 (); +extern rtx gen_sinsf2 (); +extern rtx gen_cosdf2 (); +extern rtx gen_cossf2 (); +extern rtx gen_one_cmplsi2 (); +extern rtx gen_one_cmplhi2 (); +extern rtx gen_one_cmplqi2 (); +extern rtx gen_ashldi3 (); +extern rtx gen_ashldi3_const_int (); +extern rtx gen_ashldi3_non_const_int (); +extern rtx gen_ashlsi3 (); +extern rtx gen_ashlhi3 (); +extern rtx gen_ashlqi3 (); +extern rtx gen_ashrdi3 (); +extern rtx gen_ashrdi3_const_int (); +extern rtx gen_ashrdi3_non_const_int (); +extern rtx gen_ashrsi3 (); +extern rtx gen_ashrhi3 (); +extern rtx gen_ashrqi3 (); +extern rtx gen_lshrdi3 (); +extern rtx gen_lshrdi3_const_int (); +extern rtx gen_lshrdi3_non_const_int (); +extern rtx gen_lshrsi3 (); +extern rtx gen_lshrhi3 (); +extern rtx gen_lshrqi3 (); +extern rtx gen_rotlsi3 (); +extern rtx gen_rotlhi3 (); +extern rtx gen_rotlqi3 (); +extern rtx gen_rotrsi3 (); +extern rtx gen_rotrhi3 (); +extern rtx gen_rotrqi3 (); +extern rtx gen_seq (); +extern rtx gen_sne (); +extern rtx gen_sgt (); +extern rtx gen_sgtu (); +extern rtx gen_slt (); +extern rtx gen_sltu (); +extern rtx gen_sge (); +extern rtx gen_sgeu (); +extern rtx gen_sle (); +extern rtx gen_sleu (); +extern rtx gen_beq (); +extern rtx gen_bne (); +extern rtx gen_bgt (); +extern rtx gen_bgtu (); +extern rtx gen_blt (); +extern rtx gen_bltu (); +extern rtx gen_bge (); +extern rtx gen_bgeu (); +extern rtx gen_ble (); +extern rtx gen_bleu (); +extern rtx gen_jump (); +extern rtx gen_indirect_jump (); +extern rtx gen_casesi (); +extern rtx gen_tablejump (); +extern rtx gen_untyped_call (); +extern rtx gen_untyped_return (); +extern rtx gen_update_return (); +extern rtx gen_return (); +extern rtx gen_nop (); +extern rtx gen_movstrsi (); +extern rtx gen_cmpstrsi (); +extern rtx gen_ffssi2 (); +extern rtx gen_ffshi2 (); +extern rtx gen_strlensi (); +extern rtx gen_call_pop (); +extern rtx gen_call (); +extern rtx gen_call_value_pop (); +extern rtx gen_call_value (); +#endif /* NO_MD_PROTOTYPES */ diff --git a/gnu/usr.bin/cc/include/integrate.h b/gnu/usr.bin/cc/include/integrate.h new file mode 100644 index 0000000..1176ac0 --- /dev/null +++ b/gnu/usr.bin/cc/include/integrate.h @@ -0,0 +1,125 @@ +/* Function integration definitions for GNU C-Compiler + Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This structure is used to remap objects in the function being inlined to + those belonging to the calling function. It is passed by + expand_inline_function to its children. + + This structure is also used when unrolling loops and otherwise + replicating code, although not all fields are needed in this case; + only those fields needed by copy_rtx_and_substitute() and its children + are used. + + This structure is used instead of static variables because + expand_inline_function may be called recursively via expand_expr. */ + +struct inline_remap +{ + /* True if we are doing function integration, false otherwise. + Used to control whether RTX_UNCHANGING bits are copied by + copy_rtx_and_substitute. */ + int integrating; + /* Definition of function be inlined. */ + union tree_node *fndecl; + /* Place to put insns needed at start of function. */ + rtx insns_at_start; + /* Mapping from old registers to new registers. + It is allocated and deallocated in `expand_inline_function' */ + rtx *reg_map; + /* Mapping from old code-labels to new code-labels. + The first element of this map is label_map[min_labelno]. */ + rtx *label_map; + /* Mapping from old insn uid's to copied insns. The first element + of this map is insn_map[min_insnno]; the last element is + insn_map[max_insnno]. We keep the bounds here for when the map + only covers a partial range of insns (such as loop unrolling or + code replication). */ + rtx *insn_map; + int min_insnno, max_insnno; + + /* Map pseudo reg number in calling function to equivalent constant. We + cannot in general substitute constants into parameter pseudo registers, + since some machine descriptions (many RISCs) won't always handle + the resulting insns. So if an incoming parameter has a constant + equivalent, we record it here, and if the resulting insn is + recognizable, we go with it. + + We also use this mechanism to convert references to incoming arguments + and stacked variables. copy_rtx_and_substitute will replace the virtual + incoming argument and virtual stacked variables registers with new + pseudos that contain pointers into the replacement area allocated for + this inline instance. These pseudos are then marked as being equivalent + to the appropriate address and substituted if valid. */ + rtx *const_equiv_map; + /* Number of entries in const_equiv_map and const_arg_map. */ + int const_equiv_map_size; + /* This is incremented for each new basic block. + It is used to store in const_age_map to record the domain of validity + of each entry in const_equiv_map. + A value of -1 indicates an entry for a reg which is a parm. + All other values are "positive". */ +#define CONST_AGE_PARM (-1) + unsigned int const_age; + /* In parallel with const_equiv_map, record the valid age for each entry. + The entry is invalid if its age is less than const_age. */ + unsigned int *const_age_map; + /* Target of the inline function being expanded, or NULL if none. */ + rtx inline_target; + /* When an insn is being copied by copy_rtx_and_substitute, + this is nonzero if we have copied an ASM_OPERANDS. + In that case, it is the original input-operand vector. */ + rtvec orig_asm_operands_vector; + /* When an insn is being copied by copy_rtx_and_substitute, + this is nonzero if we have copied an ASM_OPERANDS. + In that case, it is the copied input-operand vector. */ + rtvec copy_asm_operands_vector; + /* Likewise, this is the copied constraints vector. */ + rtvec copy_asm_constraints_vector; + + /* The next few fields are used for subst_constants to record the SETs + that it saw. */ + int num_sets; + struct equiv_table + { + rtx dest; + rtx equiv; + } equiv_sets[MAX_RECOG_OPERANDS]; + /* Record the last thing assigned to pc. This is used for folded + conditional branch insns. */ + rtx last_pc_value; +#ifdef HAVE_cc0 + /* Record the last thing assigned to cc0. */ + rtx last_cc0_value; +#endif +}; + +/* Return a copy of an rtx (as needed), substituting pseudo-register, + labels, and frame-pointer offsets as necessary. */ +extern rtx copy_rtx_and_substitute PROTO((rtx, struct inline_remap *)); + +extern void try_constants PROTO((rtx, struct inline_remap *)); + +extern void mark_stores PROTO((rtx, rtx)); + +/* Unfortunately, we need a global copy of const_equiv map for communication + with a function called from note_stores. Be *very* careful that this + is used properly in the presence of recursion. */ + +extern rtx *global_const_equiv_map; +extern int global_const_equiv_map_size; diff --git a/gnu/usr.bin/cc/include/longlong.h b/gnu/usr.bin/cc/include/longlong.h new file mode 100644 index 0000000..e811c73 --- /dev/null +++ b/gnu/usr.bin/cc/include/longlong.h @@ -0,0 +1,1185 @@ +/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. + Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc. + + This definition 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. + + This definition 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; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef SI_TYPE_SIZE +#define SI_TYPE_SIZE 32 +#endif + +#define __BITS4 (SI_TYPE_SIZE / 4) +#define __ll_B (1L << (SI_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((USItype) (t) % __ll_B) +#define __ll_highpart(t) ((USItype) (t) / __ll_B) + +/* Define auxiliary asm macros. + + 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) + multiplies two USItype integers MULTIPLER and MULTIPLICAND, + and generates a two-part USItype product in HIGH_PROD and + LOW_PROD. + + 2) __umulsidi3(a,b) multiplies two USItype integers A and B, + and returns a UDItype product. This is just a variant of umul_ppmm. + + 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator) divides a two-word unsigned integer, composed by the + integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and + places the quotient in QUOTIENT and the remainder in REMAINDER. + HIGH_NUMERATOR must be less than DENOMINATOR for correct operation. + If, in addition, the most significant bit of DENOMINATOR must be 1, + then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1. + + 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator). Like udiv_qrnnd but the numbers are signed. The + quotient is rounded towards 0. + + 5) count_leading_zeros(count, x) counts the number of zero-bits from + the msb to the first non-zero bit. This is the number of steps X + needs to be shifted left to set the msb. Undefined for X == 0. + + 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, + high_addend_2, low_addend_2) adds two two-word unsigned integers, + composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and + LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and + LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is + lost. + + 7) sub_ddmmss(high_difference, low_difference, high_minuend, + low_minuend, high_subtrahend, low_subtrahend) subtracts two + two-word unsigned integers, composed by HIGH_MINUEND_1 and + LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2 + respectively. The result is placed in HIGH_DIFFERENCE and + LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, + and is lost. + + If any of these macros are left undefined for a particular CPU, + C macros are used. */ + +/* The CPUs come in alphabetical order below. + + Please add support for more CPUs here, or improve the current support + for the CPUs below! + (E.g. WE32100, IBM360.) */ + +#if defined (__GNUC__) && !defined (NO_ASM) + +/* We sometimes need to clobber "cc" with gcc2, but that would not be + understood by gcc1. Use cpp to avoid major code duplication. */ +#if __GNUC__ < 2 +#define __CLOBBER_CC +#define __AND_CLOBBER_CC +#else /* __GNUC__ >= 2 */ +#define __CLOBBER_CC : "cc" +#define __AND_CLOBBER_CC , "cc" +#endif /* __GNUC__ < 2 */ + +#if defined (__a29k__) || defined (_AM29K) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %1,%4,%5 + addc %0,%2,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%r" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "%r" ((USItype)(al)), \ + "rI" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %1,%4,%5 + subc %0,%2,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "r" ((USItype)(al)), \ + "rI" ((USItype)(bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("multiplu %0,%1,%2" \ + : "=r" ((USItype)(xl)) \ + : "r" (__m0), \ + "r" (__m1)); \ + __asm__ ("multmu %0,%1,%2" \ + : "=r" ((USItype)(xh)) \ + : "r" (__m0), \ + "r" (__m1)); \ + } while (0) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("dividu %0,%3,%4" \ + : "=r" ((USItype)(q)), \ + "=q" ((USItype)(r)) \ + : "1" ((USItype)(n1)), \ + "r" ((USItype)(n0)), \ + "r" ((USItype)(d))) +#define count_leading_zeros(count, x) \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype)(count)) \ + : "r" ((USItype)(x))) +#endif /* __a29k__ */ + +#if defined (__arm__) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("adds %1, %4, %5 + adc %0, %2, %3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%r" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "%r" ((USItype)(al)), \ + "rI" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subs %1, %4, %5 + sbc %0, %2, %3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "r" ((USItype)(al)), \ + "rI" ((USItype)(bl))) +#define umul_ppmm(xh, xl, a, b) \ +{register USItype __t0, __t1, __t2; \ + __asm__ ("%@ Inlined umul_ppmm + mov %2, %5, lsr #16 + mov %0, %6, lsr #16 + bic %3, %5, %2, lsl #16 + bic %4, %6, %0, lsl #16 + mul %1, %3, %4 + mul %4, %2, %4 + mul %3, %0, %3 + mul %0, %2, %0 + adds %3, %4, %3 + addcs %0, %0, #65536 + adds %1, %1, %3, lsl #16 + adc %0, %0, %3, lsr #16" \ + : "=&r" ((USItype)(xh)), \ + "=r" ((USItype)(xl)), \ + "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ + : "r" ((USItype)(a)), \ + "r" ((USItype)(b)));} +#define UMUL_TIME 20 +#define UDIV_TIME 100 +#endif /* __arm__ */ + +#if defined (__clipper__) +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("mulwux %2,%0" \ + : "=r" (__xx.__ll) \ + : "%0" ((USItype)(u)), \ + "r" ((USItype)(v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define smul_ppmm(w1, w0, u, v) \ + ({union {DItype __ll; \ + struct {SItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("mulwx %2,%0" \ + : "=r" (__xx.__ll) \ + : "%0" ((SItype)(u)), \ + "r" ((SItype)(v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("mulwux %2,%0" \ + : "=r" (__w) \ + : "%0" ((USItype)(u)), \ + "r" ((USItype)(v))); \ + __w; }) +#endif /* __clipper__ */ + +#if defined (__gmicro__) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add.w %5,%1 + addx %3,%0" \ + : "=g" ((USItype)(sh)), \ + "=&g" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub.w %5,%1 + subx %3,%0" \ + : "=g" ((USItype)(sh)), \ + "=&g" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define umul_ppmm(ph, pl, m0, m1) \ + __asm__ ("mulx %3,%0,%1" \ + : "=g" ((USItype)(ph)), \ + "=r" ((USItype)(pl)) \ + : "%0" ((USItype)(m0)), \ + "g" ((USItype)(m1))) +#define udiv_qrnnd(q, r, nh, nl, d) \ + __asm__ ("divx %4,%0,%1" \ + : "=g" ((USItype)(q)), \ + "=r" ((USItype)(r)) \ + : "1" ((USItype)(nh)), \ + "0" ((USItype)(nl)), \ + "g" ((USItype)(d))) +#define count_leading_zeros(count, x) \ + __asm__ ("bsch/1 %1,%0" \ + : "=g" (count) \ + : "g" ((USItype)(x)), \ + "0" ((USItype)0)) +#endif + +#if defined (__hppa) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %4,%5,%1 + addc %2,%3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%rM" ((USItype)(ah)), \ + "rM" ((USItype)(bh)), \ + "%rM" ((USItype)(al)), \ + "rM" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %4,%5,%1 + subb %2,%3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "rM" ((USItype)(ah)), \ + "rM" ((USItype)(bh)), \ + "rM" ((USItype)(al)), \ + "rM" ((USItype)(bl))) +#if defined (_PA_RISC1_1) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + union \ + { \ + UDItype __f; \ + struct {USItype __w1, __w0;} __w1w0; \ + } __t; \ + __asm__ ("xmpyu %1,%2,%0" \ + : "=x" (__t.__f) \ + : "x" ((USItype)(u)), \ + "x" ((USItype)(v))); \ + (w1) = __t.__w1w0.__w1; \ + (w0) = __t.__w1w0.__w0; \ + } while (0) +#define UMUL_TIME 8 +#else +#define UMUL_TIME 30 +#endif +#define UDIV_TIME 40 +#define count_leading_zeros(count, x) \ + do { \ + USItype __tmp; \ + __asm__ ( \ + "ldi 1,%0 + extru,= %1,15,16,%%r0 ; Bits 31..16 zero? + extru,tr %1,15,16,%1 ; No. Shift down, skip add. + ldo 16(%0),%0 ; Yes. Perform add. + extru,= %1,23,8,%%r0 ; Bits 15..8 zero? + extru,tr %1,23,8,%1 ; No. Shift down, skip add. + ldo 8(%0),%0 ; Yes. Perform add. + extru,= %1,27,4,%%r0 ; Bits 7..4 zero? + extru,tr %1,27,4,%1 ; No. Shift down, skip add. + ldo 4(%0),%0 ; Yes. Perform add. + extru,= %1,29,2,%%r0 ; Bits 3..2 zero? + extru,tr %1,29,2,%1 ; No. Shift down, skip add. + ldo 2(%0),%0 ; Yes. Perform add. + extru %1,30,1,%1 ; Extract bit 1. + sub %0,%1,%0 ; Subtract it. + " : "=r" (count), "=r" (__tmp) : "1" (x)); \ + } while (0) +#endif + +#if defined (__i386__) || defined (__i486__) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl %5,%1 + adcl %3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl %5,%1 + sbbl %3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mull %3" \ + : "=a" ((USItype)(w0)), \ + "=d" ((USItype)(w1)) \ + : "%0" ((USItype)(u)), \ + "rm" ((USItype)(v))) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divl %4" \ + : "=a" ((USItype)(q)), \ + "=d" ((USItype)(r)) \ + : "0" ((USItype)(n0)), \ + "1" ((USItype)(n1)), \ + "rm" ((USItype)(d))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("bsrl %1,%0" \ + : "=r" (__cbtmp) : "rm" ((USItype)(x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#define UMUL_TIME 40 +#define UDIV_TIME 40 +#endif /* 80x86 */ + +#if defined (__i860__) +#if 0 +/* Make sure these patterns really improve the code before + switching them on. */ +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + union \ + { \ + DItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __a, __b, __s; \ + __a.__i.__l = (al); \ + __a.__i.__h = (ah); \ + __b.__i.__l = (bl); \ + __b.__i.__h = (bh); \ + __asm__ ("fiadd.dd %1,%2,%0" \ + : "=f" (__s.__ll) \ + : "%f" (__a.__ll), "f" (__b.__ll)); \ + (sh) = __s.__i.__h; \ + (sl) = __s.__i.__l; \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + union \ + { \ + DItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __a, __b, __s; \ + __a.__i.__l = (al); \ + __a.__i.__h = (ah); \ + __b.__i.__l = (bl); \ + __b.__i.__h = (bh); \ + __asm__ ("fisub.dd %1,%2,%0" \ + : "=f" (__s.__ll) \ + : "%f" (__a.__ll), "f" (__b.__ll)); \ + (sh) = __s.__i.__h; \ + (sl) = __s.__i.__l; \ + } while (0) +#endif +#endif /* __i860__ */ + +#if defined (__i960__) +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__xx.__ll) \ + : "%dI" ((USItype)(u)), \ + "dI" ((USItype)(v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__w) \ + : "%dI" ((USItype)(u)), \ + "dI" ((USItype)(v))); \ + __w; }) +#endif /* __i960__ */ + +#if defined (__mc68000__) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add%.l %5,%1 + addx%.l %3,%0" \ + : "=d" ((USItype)(sh)), \ + "=&d" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "d" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub%.l %5,%1 + subx%.l %3,%0" \ + : "=d" ((USItype)(sh)), \ + "=&d" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "d" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#if defined (__mc68020__) || defined (__NeXT__) || defined(mc68020) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mulu%.l %3,%1:%0" \ + : "=d" ((USItype)(w0)), \ + "=d" ((USItype)(w1)) \ + : "%0" ((USItype)(u)), \ + "dmi" ((USItype)(v))) +#define UMUL_TIME 45 +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divu%.l %4,%1:%0" \ + : "=d" ((USItype)(q)), \ + "=d" ((USItype)(r)) \ + : "0" ((USItype)(n0)), \ + "1" ((USItype)(n1)), \ + "dmi" ((USItype)(d))) +#define UDIV_TIME 90 +#define sdiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divs%.l %4,%1:%0" \ + : "=d" ((USItype)(q)), \ + "=d" ((USItype)(r)) \ + : "0" ((USItype)(n0)), \ + "1" ((USItype)(n1)), \ + "dmi" ((USItype)(d))) +#define count_leading_zeros(count, x) \ + __asm__ ("bfffo %1{%b2:%b2},%0" \ + : "=d" ((USItype)(count)) \ + : "od" ((USItype)(x)), "n" (0)) +#else /* not mc68020 */ +/* %/ inserts REGISTER_PREFIX. */ +#define umul_ppmm(xh, xl, a, b) \ + __asm__ ("| Inlined umul_ppmm + move%.l %2,%/d0 + move%.l %3,%/d1 + move%.l %/d0,%/d2 + swap %/d0 + move%.l %/d1,%/d3 + swap %/d1 + move%.w %/d2,%/d4 + mulu %/d3,%/d4 + mulu %/d1,%/d2 + mulu %/d0,%/d3 + mulu %/d0,%/d1 + move%.l %/d4,%/d0 + eor%.w %/d0,%/d0 + swap %/d0 + add%.l %/d0,%/d2 + add%.l %/d3,%/d2 + jcc 1f + add%.l #65536,%/d1 +1: swap %/d2 + moveq #0,%/d0 + move%.w %/d2,%/d0 + move%.w %/d4,%/d2 + move%.l %/d2,%1 + add%.l %/d1,%/d0 + move%.l %/d0,%0" \ + : "=g" ((USItype)(xh)), \ + "=g" ((USItype)(xl)) \ + : "g" ((USItype)(a)), \ + "g" ((USItype)(b)) \ + : "d0", "d1", "d2", "d3", "d4") +#define UMUL_TIME 100 +#define UDIV_TIME 400 +#endif /* not mc68020 */ +#endif /* mc68000 */ + +#if defined (__m88000__) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addu.co %1,%r4,%r5 + addu.ci %0,%r2,%r3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%rJ" ((USItype)(ah)), \ + "rJ" ((USItype)(bh)), \ + "%rJ" ((USItype)(al)), \ + "rJ" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subu.co %1,%r4,%r5 + subu.ci %0,%r2,%r3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "rJ" ((USItype)(ah)), \ + "rJ" ((USItype)(bh)), \ + "rJ" ((USItype)(al)), \ + "rJ" ((USItype)(bl))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("ff1 %0,%1" \ + : "=r" (__cbtmp) \ + : "r" ((USItype)(x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#if defined (__mc88110__) +#define umul_ppmm(wh, wl, u, v) \ + do { \ + union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __asm__ ("mulu.d %0,%1,%2" \ + : "=r" (__xx.__ll) \ + : "r" ((USItype)(u)), \ + "r" ((USItype)(v))); \ + (wh) = __xx.__i.__h; \ + (wl) = __xx.__i.__l; \ + } while (0) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + USItype __q; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("divu.d %0,%1,%2" \ + : "=r" (__q) \ + : "r" (__xx.__ll), \ + "r" ((USItype)(d))); \ + (r) = (n0) - __q * (d); (q) = __q; }) +#define UMUL_TIME 5 +#define UDIV_TIME 25 +#else +#define UMUL_TIME 17 +#define UDIV_TIME 150 +#endif /* __mc88110__ */ +#endif /* __m88000__ */ + +#if defined (__mips__) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("multu %2,%3 + mflo %0 + mfhi %1" \ + : "=d" ((USItype)(w0)), \ + "=d" ((USItype)(w1)) \ + : "d" ((USItype)(u)), \ + "d" ((USItype)(v))) +#define UMUL_TIME 10 +#define UDIV_TIME 100 +#endif /* __mips__ */ + +#if defined (__ns32000__) +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("meid %2,%0" \ + : "=g" (__xx.__ll) \ + : "%0" ((USItype)(u)), \ + "g" ((USItype)(v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("meid %2,%0" \ + : "=g" (__w) \ + : "%0" ((USItype)(u)), \ + "g" ((USItype)(v))); \ + __w; }) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("deid %2,%0" \ + : "=g" (__xx.__ll) \ + : "0" (__xx.__ll), \ + "g" ((USItype)(d))); \ + (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) +#endif /* __ns32000__ */ + +#if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%r" ((USItype)(ah)), \ + "%r" ((USItype)(al)), \ + "rI" ((USItype)(bl))); \ + else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%r" ((USItype)(ah)), \ + "%r" ((USItype)(al)), \ + "rI" ((USItype)(bl))); \ + else \ + __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%r" ((USItype)(ah)), \ + "r" ((USItype)(bh)), \ + "%r" ((USItype)(al)), \ + "rI" ((USItype)(bl))); \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (ah) && (ah) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(bh)), \ + "rI" ((USItype)(al)), \ + "r" ((USItype)(bl))); \ + else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(bh)), \ + "rI" ((USItype)(al)), \ + "r" ((USItype)(bl))); \ + else if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(ah)), \ + "rI" ((USItype)(al)), \ + "r" ((USItype)(bl))); \ + else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(ah)), \ + "rI" ((USItype)(al)), \ + "r" ((USItype)(bl))); \ + else \ + __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "r" ((USItype)(ah)), \ + "r" ((USItype)(bh)), \ + "rI" ((USItype)(al)), \ + "r" ((USItype)(bl))); \ + } while (0) +#define count_leading_zeros(count, x) \ + __asm__ ("{cntlz|cntlzw} %0,%1" \ + : "=r" ((USItype)(count)) \ + : "r" ((USItype)(x))) +#if defined (_ARCH_PPC) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhwu %0,%1,%2" \ + : "=r" ((USItype) ph) \ + : "%r" (__m0), \ + "r" (__m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 15 +#define smul_ppmm(ph, pl, m0, m1) \ + do { \ + SItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhw %0,%1,%2" \ + : "=r" ((SItype) ph) \ + : "%r" (__m0), \ + "r" (__m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define SMUL_TIME 14 +#define UDIV_TIME 120 +#else +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mul %0,%2,%3" \ + : "=r" ((USItype)(xh)), \ + "=q" ((USItype)(xl)) \ + : "r" (__m0), \ + "r" (__m1)); \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define UMUL_TIME 8 +#define smul_ppmm(xh, xl, m0, m1) \ + __asm__ ("mul %0,%2,%3" \ + : "=r" ((SItype)(xh)), \ + "=q" ((SItype)(xl)) \ + : "r" (m0), \ + "r" (m1)) +#define SMUL_TIME 4 +#define sdiv_qrnnd(q, r, nh, nl, d) \ + __asm__ ("div %0,%2,%4" \ + : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \ + : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d))) +#define UDIV_TIME 100 +#endif +#endif /* Power architecture variants. */ + +#if defined (__pyr__) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addw %5,%1 + addwc %3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subw %5,%1 + subwb %3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +/* This insn doesn't work on ancient pyramids. */ +#define umul_ppmm(w1, w0, u, v) \ + ({union { \ + UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __xx.__i.__l = u; \ + __asm__ ("uemul %3,%0" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "1" (__xx.__i.__l), \ + "g" ((USItype)(v))); \ + (w1) = __xx.__i.__h; \ + (w0) = __xx.__i.__l;}) +#endif /* __pyr__ */ + +#if defined (__ibm032__) /* RT/ROMP */ +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("a %1,%5 + ae %0,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "r" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "r" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("s %1,%5 + se %0,%3" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "r" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "r" ((USItype)(bl))) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ( \ + "s r2,r2 + mts r10,%2 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + m r2,%3 + cas %0,r2,r0 + mfs r10,%1" \ + : "=r" ((USItype)(ph)), \ + "=r" ((USItype)(pl)) \ + : "%r" (__m0), \ + "r" (__m1) \ + : "r2"); \ + (ph) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define UMUL_TIME 20 +#define UDIV_TIME 200 +#define count_leading_zeros(count, x) \ + do { \ + if ((x) >= 0x10000) \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype)(count)) \ + : "r" ((USItype)(x) >> 16)); \ + else \ + { \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype)(count)) \ + : "r" ((USItype)(x))); \ + (count) += 16; \ + } \ + } while (0) +#endif + +#if defined (__sparc__) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %r4,%5,%1 + addx %r2,%3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "%rJ" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "%rJ" ((USItype)(al)), \ + "rI" ((USItype)(bl)) \ + __CLOBBER_CC) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %r4,%5,%1 + subx %r2,%3,%0" \ + : "=r" ((USItype)(sh)), \ + "=&r" ((USItype)(sl)) \ + : "rJ" ((USItype)(ah)), \ + "rI" ((USItype)(bh)), \ + "rJ" ((USItype)(al)), \ + "rI" ((USItype)(bl)) \ + __CLOBBER_CC) +#if defined (__sparc_v8__) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype)(w1)), \ + "=r" ((USItype)(w0)) \ + : "r" ((USItype)(u)), \ + "r" ((USItype)(v))) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ + : "=&r" ((USItype)(q)), \ + "=&r" ((USItype)(r)) \ + : "r" ((USItype)(n1)), \ + "r" ((USItype)(n0)), \ + "r" ((USItype)(d))) +#else +#if defined (__sparclite__) +/* This has hardware multiply but not divide. It also has two additional + instructions scan (ffs from high bit) and divscc. */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype)(w1)), \ + "=r" ((USItype)(w0)) \ + : "r" ((USItype)(u)), \ + "r" ((USItype)(v))) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("! Inlined udiv_qrnnd + wr %%g0,%2,%%y ! Not a delayed write for sparclite + tst %%g0 + divscc %3,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%%g1 + divscc %%g1,%4,%0 + rd %%y,%1 + bl,a 1f + add %1,%4,%1 +1: ! End of inline udiv_qrnnd" \ + : "=r" ((USItype)(q)), \ + "=r" ((USItype)(r)) \ + : "r" ((USItype)(n1)), \ + "r" ((USItype)(n0)), \ + "rI" ((USItype)(d)) \ + : "%g1" __AND_CLOBBER_CC) +#define UDIV_TIME 37 +#define count_leading_zeros(count, x) \ + __asm__ ("scan %1,0,%0" \ + : "=r" ((USItype)(x)) \ + : "r" ((USItype)(count))) +#else +/* SPARC without integer multiplication and divide instructions. + (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("! Inlined umul_ppmm + wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr + sra %3,31,%%g2 ! Don't move this insn + and %2,%%g2,%%g2 ! Don't move this insn + andcc %%g0,0,%%g1 ! Don't move this insn + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,%3,%%g1 + mulscc %%g1,0,%%g1 + add %%g1,%%g2,%0 + rd %%y,%1" \ + : "=r" ((USItype)(w1)), \ + "=r" ((USItype)(w0)) \ + : "%rI" ((USItype)(u)), \ + "r" ((USItype)(v)) \ + : "%g1", "%g2" __AND_CLOBBER_CC) +#define UMUL_TIME 39 /* 39 instructions */ +/* It's quite necessary to add this much assembler for the sparc. + The default udiv_qrnnd (in C) is more than 10 times slower! */ +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("! Inlined udiv_qrnnd + mov 32,%%g1 + subcc %1,%2,%%g0 +1: bcs 5f + addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb + sub %1,%2,%1 ! this kills msb of n + addx %1,%1,%1 ! so this can't give carry + subcc %%g1,1,%%g1 +2: bne 1b + subcc %1,%2,%%g0 + bcs 3f + addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb + b 3f + sub %1,%2,%1 ! this kills msb of n +4: sub %1,%2,%1 +5: addxcc %1,%1,%1 + bcc 2b + subcc %%g1,1,%%g1 +! Got carry from n. Subtract next step to cancel this carry. + bne 4b + addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb + sub %1,%2,%1 +3: xnor %0,0,%0 + ! End of inline udiv_qrnnd" \ + : "=&r" ((USItype)(q)), \ + "=&r" ((USItype)(r)) \ + : "r" ((USItype)(d)), \ + "1" ((USItype)(n1)), \ + "0" ((USItype)(n0)) : "%g1" __AND_CLOBBER_CC) +#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ +#endif /* __sparclite__ */ +#endif /* __sparc_v8__ */ +#endif /* __sparc__ */ + +#if defined (__vax__) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl2 %5,%1 + adwc %3,%0" \ + : "=g" ((USItype)(sh)), \ + "=&g" ((USItype)(sl)) \ + : "%0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "%1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl2 %5,%1 + sbwc %3,%0" \ + : "=g" ((USItype)(sh)), \ + "=&g" ((USItype)(sl)) \ + : "0" ((USItype)(ah)), \ + "g" ((USItype)(bh)), \ + "1" ((USItype)(al)), \ + "g" ((USItype)(bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union { \ + UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("emul %1,%2,$0,%0" \ + : "=r" (__xx.__ll) \ + : "g" (__m0), \ + "g" (__m1)); \ + (xh) = __xx.__i.__h; \ + (xl) = __xx.__i.__l; \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {SItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = n1; __xx.__i.__l = n0; \ + __asm__ ("ediv %3,%2,%0,%1" \ + : "=g" (q), "=g" (r) \ + : "g" (__xx.__ll), "g" (d)); \ + } while (0) +#endif /* __vax__ */ + +#endif /* __GNUC__ */ + +/* If this machine has no inline assembler, use C macros. */ + +#if !defined (add_ssaaaa) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + USItype __x; \ + __x = (al) + (bl); \ + (sh) = (ah) + (bh) + (__x < (al)); \ + (sl) = __x; \ + } while (0) +#endif + +#if !defined (sub_ddmmss) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + USItype __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - (__x > (al)); \ + (sl) = __x; \ + } while (0) +#endif + +#if !defined (umul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + USItype __x0, __x1, __x2, __x3; \ + USItype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (USItype) __ul * __vl; \ + __x1 = (USItype) __ul * __vh; \ + __x2 = (USItype) __uh * __vl; \ + __x3 = (USItype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ + } while (0) +#endif + +#if !defined (__umulsidi3) +#define __umulsidi3(u, v) \ + ({DIunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) +#endif + +/* Define this unconditionally, so it can be used for debugging. */ +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + USItype __d1, __d0, __q1, __q0; \ + USItype __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (USItype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (USItype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (USItype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through + __udiv_w_sdiv (defined in libgcc or elsewhere). */ +#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) +#define udiv_qrnnd(q, r, nh, nl, d) \ + do { \ + USItype __r; \ + (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ + (r) = __r; \ + } while (0) +#endif + +/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ +#if !defined (udiv_qrnnd) +#define UDIV_NEEDS_NORMALIZATION 1 +#define udiv_qrnnd __udiv_qrnnd_c +#endif + +#if !defined (count_leading_zeros) +extern const UQItype __clz_tab[]; +#define count_leading_zeros(count, x) \ + do { \ + USItype __xr = (x); \ + USItype __a; \ + \ + if (SI_TYPE_SIZE <= 32) \ + { \ + __a = __xr < (1<<2*__BITS4) \ + ? (__xr < (1<<__BITS4) ? 0 : __BITS4) \ + : (__xr < (1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ + } \ + else \ + { \ + for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \ + if (((__xr >> __a) & 0xff) != 0) \ + break; \ + } \ + \ + (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ + } while (0) +#endif + +#ifndef UDIV_NEEDS_NORMALIZATION +#define UDIV_NEEDS_NORMALIZATION 0 +#endif diff --git a/gnu/usr.bin/cc/include/loop.h b/gnu/usr.bin/cc/include/loop.h new file mode 100644 index 0000000..bb219c3 --- /dev/null +++ b/gnu/usr.bin/cc/include/loop.h @@ -0,0 +1,169 @@ +/* Loop optimization definitions for GNU C-Compiler + Copyright (C) 1991 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Get the luid of an insn. Catch the error of trying to reference the LUID + of an insn added during loop, since these don't have LUIDs. */ + +#define INSN_LUID(INSN) \ + (INSN_UID (INSN) < max_uid_for_loop ? uid_luid[INSN_UID (INSN)] \ + : (abort (), -1)) + +/* A "basic induction variable" or biv is a pseudo reg that is set + (within this loop) only by incrementing or decrementing it. */ +/* A "general induction variable" or giv is a pseudo reg whose + value is a linear function of a biv. */ + +/* Bivs are recognized by `basic_induction_var'; + Givs by `general_induct_var'. */ + +/* An enum for the two different types of givs, those that are used + as memory addresses and those that are calculated into registers. */ +enum g_types { DEST_ADDR, DEST_REG }; + +/* A `struct induction' is created for every instruction that sets + an induction variable (either a biv or a giv). */ + +struct induction +{ + rtx insn; /* The insn that sets a biv or giv */ + rtx new_reg; /* New register, containing strength reduced + version of this giv. */ + rtx src_reg; /* Biv from which this giv is computed. + (If this is a biv, then this is the biv.) */ + enum g_types giv_type; /* Indicate whether DEST_ADDR or DEST_REG */ + rtx dest_reg; /* Destination register for insn: this is the + register which was the biv or giv. + For a biv, this equals src_reg. + For a DEST_ADDR type giv, this is 0. */ + rtx *location; /* Place in the insn where this giv occurs. + If GIV_TYPE is DEST_REG, this is 0. */ + enum machine_mode mode; /* The mode of this biv or giv */ + enum machine_mode mem_mode; /* For DEST_ADDR, mode of the memory object. */ + rtx mult_val; /* Multiplicative factor for src_reg. */ + rtx add_val; /* Additive constant for that product. */ + int benefit; /* Gain from eliminating this insn. */ + rtx final_value; /* If the giv is used outside the loop, and its + final value could be calculated, it is put + here, and the giv is made replaceable. Set + the giv to this value before the loop. */ + unsigned replaceable : 1; /* 1 if we can substitute the strength-reduced + variable for the original variable. + 0 means they must be kept separate and the + new one must be copied into the old pseudo + reg each time the old one is set. */ + unsigned not_replaceable : 1; /* Used to prevent duplicating work. This is + 1 if we know that the giv definitely can + not be made replaceable, in which case we + don't bother checking the variable again + even if further info is available. + Both this and the above can be zero. */ + unsigned ignore : 1; /* 1 prohibits further processing of giv */ + unsigned always_computable : 1;/* 1 if this set occurs each iteration */ + unsigned maybe_multiple : 1; /* Only used for a biv and 1 if this biv + update may be done multiple times per + iteration. */ + unsigned cant_derive : 1; /* For giv's, 1 if this giv cannot derive + another giv. This occurs in many cases + where a giv's lifetime spans an update to + a biv. */ + unsigned combined_with : 1; /* 1 if this giv has been combined with. It + then cannot combine with any other giv. */ + unsigned maybe_dead : 1; /* 1 if this giv might be dead. In that case, + we won't use it to eliminate a biv, it + would probably lose. */ + int lifetime; /* Length of life of this giv */ + int times_used; /* # times this giv is used. */ + rtx derive_adjustment; /* If nonzero, is an adjustment to be + subtracted from add_val when this giv + derives another. This occurs when the + giv spans a biv update by incrementation. */ + struct induction *next_iv; /* For givs, links together all givs that are + based on the same biv. For bivs, links + together all biv entries that refer to the + same biv register. */ + struct induction *same; /* If this giv has been combined with another + giv, this points to the base giv. The base + giv will have COMBINED_WITH non-zero. */ + HOST_WIDE_INT const_adjust; /* Used by loop unrolling, when an address giv + is split, and a constant is eliminated from + the address, the -constant is stored here + for later use. */ +}; + +/* A `struct iv_class' is created for each biv. */ + +struct iv_class { + int regno; /* Pseudo reg which is the biv. */ + int biv_count; /* Number of insns setting this reg. */ + struct induction *biv; /* List of all insns that set this reg. */ + int giv_count; /* Number of DEST_REG givs computed from this + biv. The resulting count is only used in + check_dbra_loop. */ + struct induction *giv; /* List of all insns that compute a giv + from this reg. */ + int total_benefit; /* Sum of BENEFITs of all those givs */ + rtx initial_value; /* Value of reg at loop start */ + rtx initial_test; /* Test performed on BIV before loop */ + struct iv_class *next; /* Links all class structures together */ + rtx init_insn; /* insn which initializes biv, 0 if none. */ + rtx init_set; /* SET of INIT_INSN, if any. */ + unsigned incremented : 1; /* 1 if somewhere incremented/decremented */ + unsigned eliminable : 1; /* 1 if plausible candidate for elimination. */ + unsigned nonneg : 1; /* 1 if we added a REG_NONNEG note for this. */ + unsigned reversed : 1; /* 1 if we reversed the loop that this + biv controls. */ +}; + +/* Definitions used by the basic induction variable discovery code. */ +enum iv_mode { UNKNOWN_INDUCT, BASIC_INDUCT, NOT_BASIC_INDUCT, + GENERAL_INDUCT }; + +/* Variables declared in loop.c, but also needed in unroll.c. */ + +extern int *uid_luid; +extern int max_uid_for_loop; +extern int *uid_loop_num; +extern int *loop_outer_loop; +extern rtx *loop_number_exit_labels; +extern unsigned HOST_WIDE_INT loop_n_iterations; +extern int max_reg_before_loop; + +extern FILE *loop_dump_stream; + +extern enum iv_mode *reg_iv_type; +extern struct induction **reg_iv_info; +extern struct iv_class **reg_biv_class; +extern struct iv_class *loop_iv_list; + +/* Forward declarations for non-static functions declared in loop.c and + unroll.c. */ +int invariant_p PROTO((rtx)); +rtx get_condition_for_loop PROTO((rtx)); +void emit_iv_add_mult PROTO((rtx, rtx, rtx, rtx, rtx)); + +/* Forward declarations for non-static functions declared in stmt.c. */ +void find_loop_tree_blocks PROTO((void)); +void unroll_block_trees PROTO((void)); + +void unroll_loop PROTO((rtx, int, rtx, rtx, int)); +rtx biv_total_increment PROTO((struct iv_class *, rtx, rtx)); +unsigned HOST_WIDE_INT loop_iterations PROTO((rtx, rtx)); +rtx final_biv_value PROTO((struct iv_class *, rtx, rtx)); +rtx final_giv_value PROTO((struct induction *, rtx, rtx)); +void emit_unrolled_add PROTO((rtx, rtx, rtx)); diff --git a/gnu/usr.bin/cc/include/machmode.def b/gnu/usr.bin/cc/include/machmode.def new file mode 100644 index 0000000..24d0ba5 --- /dev/null +++ b/gnu/usr.bin/cc/include/machmode.def @@ -0,0 +1,118 @@ +/* This file contains the definitions and documentation for the + machine modes used in the the GNU compiler. + Copyright (C) 1987, 1992, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* This file defines all the MACHINE MODES used by GNU CC. + + A machine mode specifies a size and format of data + at the machine level. + + Each RTL expression has a machine mode. + + At the syntax tree level, each ..._TYPE and each ..._DECL node + has a machine mode which describes data of that type or the + data of the variable declared. */ + +/* The first argument is the internal name of the machine mode + used in the C source. + By convention these are in UPPER_CASE, except for the word "mode". + + The second argument is the name of the machine mode in the + external ASCII format used for reading and printing RTL and trees. + By convention these names in UPPER_CASE. + + Third argument states the kind of representation: + MODE_INT - integer + MODE_FLOAT - floating + MODE_PARTIAL_INT - PSImode and PDImode + MODE_CC - modes used for representing the condition code in a register + MODE_COMPLEX_INT, MODE_COMPLEX_FLOAT - complex number + MODE_RANDOM - anything else + + Fourth argument is the relative size of the object, in bytes. + It is zero when the size is meaningless or not determined. + A byte's size is determined by BITS_PER_UNIT in tm.h. + + + Fifth arg is the relative size of subunits of the object. + It is same as the fourth argument except for complexes, + since they are really made of two equal size subunits. + + Sixth arg is next wider natural mode of the same class. + 0 if there is none. */ + +/* VOIDmode is used when no mode needs to be specified, + as for example on CONST_INT RTL expressions. */ +DEF_MACHMODE (VOIDmode, "VOID", MODE_RANDOM, 0, 0, VOIDmode) + +DEF_MACHMODE (QImode, "QI", MODE_INT, 1, 1, HImode) /* int types */ +DEF_MACHMODE (HImode, "HI", MODE_INT, 2, 2, SImode) +/* Pointers on some machines use this type to distinguish them from ints. + Useful if a pointer is 4 bytes but has some bits that are not significant, + so it is really not quite as wide as an integer. */ +DEF_MACHMODE (PSImode, "PSI", MODE_PARTIAL_INT, 4, 4, VOIDmode) +DEF_MACHMODE (SImode, "SI", MODE_INT, 4, 4, DImode) +DEF_MACHMODE (PDImode, "PDI", MODE_PARTIAL_INT, 8, 8, VOIDmode) +DEF_MACHMODE (DImode, "DI", MODE_INT, 8, 8, TImode) +DEF_MACHMODE (TImode, "TI", MODE_INT, 16, 16, OImode) +DEF_MACHMODE (OImode, "OI", MODE_INT, 32, 32, VOIDmode) + +DEF_MACHMODE (QFmode, "QF", MODE_FLOAT, 1, 1, HFmode) +DEF_MACHMODE (HFmode, "HF", MODE_FLOAT, 2, 2, TQFmode) +DEF_MACHMODE (TQFmode, "TQF", MODE_FLOAT, 3, 3, SFmode) /* MIL-STD-1750A */ +DEF_MACHMODE (SFmode, "SF", MODE_FLOAT, 4, 4, DFmode) +DEF_MACHMODE (DFmode, "DF", MODE_FLOAT, 8, 8, XFmode) +DEF_MACHMODE (XFmode, "XF", MODE_FLOAT, 12, 12, TFmode) /* IEEE extended */ +DEF_MACHMODE (TFmode, "TF", MODE_FLOAT, 16, 16, VOIDmode) + +/* Complex modes. */ +DEF_MACHMODE (SCmode, "SC", MODE_COMPLEX_FLOAT, 8, 4, DCmode) +DEF_MACHMODE (DCmode, "DC", MODE_COMPLEX_FLOAT, 16, 8, XCmode) +DEF_MACHMODE (XCmode, "XC", MODE_COMPLEX_FLOAT, 24, 12, TCmode) +DEF_MACHMODE (TCmode, "TC", MODE_COMPLEX_FLOAT, 32, 16, VOIDmode) + +DEF_MACHMODE (CQImode, "CQI", MODE_COMPLEX_INT, 2, 1, CHImode) +DEF_MACHMODE (CHImode, "CHI", MODE_COMPLEX_INT, 4, 2, CSImode) +DEF_MACHMODE (CSImode, "CSI", MODE_COMPLEX_INT, 8, 4, CDImode) +DEF_MACHMODE (CDImode, "CDI", MODE_COMPLEX_INT, 16, 8, CTImode) +DEF_MACHMODE (CTImode, "CTI", MODE_COMPLEX_INT, 32, 16, COImode) +DEF_MACHMODE (COImode, "COI", MODE_COMPLEX_INT, 64, 32, VOIDmode) + +/* BLKmode is used for structures, arrays, etc. + that fit no more specific mode. */ +DEF_MACHMODE (BLKmode, "BLK", MODE_RANDOM, 0, 0, VOIDmode) + +/* The modes for representing the condition codes come last. CCmode is + always defined. Additional modes for the condition code can be specified + in the EXTRA_CC_MODES macro. Everything but the names of the modes + are copied from CCmode. For these modes, GET_MODE_WIDER_MODE points + to the next defined CC mode, if any. */ + +DEF_MACHMODE (CCmode, "CC", MODE_CC, 4, 4, VOIDmode) + +/* The symbol Pmode stands for one of the above machine modes (usually SImode). + The tm file specifies which one. It is not a distinct mode. */ + +/* +Local variables: +mode:c +version-control: t +End: +*/ diff --git a/gnu/usr.bin/cc/include/machmode.h b/gnu/usr.bin/cc/include/machmode.h new file mode 100644 index 0000000..307422b --- /dev/null +++ b/gnu/usr.bin/cc/include/machmode.h @@ -0,0 +1,169 @@ +/* Machine mode definitions for GNU C-Compiler; included by rtl.h and tree.h. + Copyright (C) 1991, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* Add prototype support. */ +#ifndef PROTO +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define PROTO(ARGS) ARGS +#else +#define PROTO(ARGS) () +#endif +#endif + +#ifndef HAVE_MACHINE_MODES + +/* Strictly speaking, this isn't the proper place to include these definitions, + but this file is included by every GCC file. + + Some systems define these in, e.g., param.h. We undefine these names + here to avoid the warnings. We prefer to use our definitions since we + know they are correct. */ + +#undef MIN +#undef MAX + +#define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) +#define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) + +/* Find the largest host integer type and set its size and type. */ + +#ifndef HOST_BITS_PER_WIDE_INT + +#if HOST_BITS_PER_LONG > HOST_BITS_PER_INT +#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_LONG +#define HOST_WIDE_INT long +#else +#define HOST_BITS_PER_WIDE_INT HOST_BITS_PER_INT +#define HOST_WIDE_INT int +#endif + +#endif + +/* Provide a default way to print an address in hex via printf. */ + +#ifndef HOST_PTR_PRINTF +#define HOST_PTR_PRINTF sizeof (int) == sizeof (char *) ? "%x" : "%lx" +#endif + +/* Make an enum class that gives all the machine modes. */ + +#define DEF_MACHMODE(SYM, NAME, TYPE, SIZE, UNIT, WIDER) SYM, + +enum machine_mode { +#include "machmode.def" + +#ifdef EXTRA_CC_MODES + EXTRA_CC_MODES, +#endif +MAX_MACHINE_MODE }; + +#undef DEF_MACHMODE + +#define HAVE_MACHINE_MODES + +#ifndef NUM_MACHINE_MODES +#define NUM_MACHINE_MODES (int) MAX_MACHINE_MODE +#endif + +/* Get the name of mode MODE as a string. */ + +extern char *mode_name[]; +#define GET_MODE_NAME(MODE) (mode_name[(int)(MODE)]) + +enum mode_class { MODE_RANDOM, MODE_INT, MODE_FLOAT, MODE_PARTIAL_INT, MODE_CC, + MODE_COMPLEX_INT, MODE_COMPLEX_FLOAT, MAX_MODE_CLASS}; + +/* Get the general kind of object that mode MODE represents + (integer, floating, complex, etc.) */ + +extern enum mode_class mode_class[]; +#define GET_MODE_CLASS(MODE) (mode_class[(int)(MODE)]) + +/* Nonzero if MODE is an integral mode. */ +#define INTEGRAL_MODE_P(MODE) \ + (GET_MODE_CLASS (MODE) == MODE_INT \ + || GET_MODE_CLASS (MODE) == MODE_PARTIAL_INT \ + || GET_MODE_CLASS (MODE) == MODE_COMPLEX_INT) + +/* Nonzero if MODE is a floating-point mode. */ +#define FLOAT_MODE_P(MODE) \ + (GET_MODE_CLASS (MODE) == MODE_FLOAT \ + || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) + +/* Get the size in bytes of an object of mode MODE. */ + +extern int mode_size[]; +#define GET_MODE_SIZE(MODE) (mode_size[(int)(MODE)]) + +/* Get the size in bytes of the basic parts of an object of mode MODE. */ + +extern int mode_unit_size[]; +#define GET_MODE_UNIT_SIZE(MODE) (mode_unit_size[(int)(MODE)]) + +/* Get the number of units in the object. */ + +#define GET_MODE_NUNITS(MODE) \ + ((GET_MODE_UNIT_SIZE ((MODE)) == 0) ? 0 \ + : (GET_MODE_SIZE ((MODE)) / GET_MODE_UNIT_SIZE ((MODE)))) + +/* Get the size in bits of an object of mode MODE. */ + +#define GET_MODE_BITSIZE(MODE) (BITS_PER_UNIT * mode_size[(int)(MODE)]) + +/* Get a bitmask containing 1 for all bits in a word + that fit within mode MODE. */ + +#define GET_MODE_MASK(MODE) \ + ((GET_MODE_BITSIZE (MODE) >= HOST_BITS_PER_WIDE_INT) \ + ?(HOST_WIDE_INT) ~0 : (((HOST_WIDE_INT) 1 << GET_MODE_BITSIZE (MODE)) - 1)) + +/* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI). */ + +extern enum machine_mode mode_wider_mode[]; +#define GET_MODE_WIDER_MODE(MODE) (mode_wider_mode[(int)(MODE)]) + +/* Return the mode for data of a given size SIZE and mode class CLASS. + If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE. + The value is BLKmode if no other mode is found. */ + +extern enum machine_mode mode_for_size PROTO((unsigned int, enum mode_class, int)); + +/* Find the best mode to use to access a bit field. */ + +extern enum machine_mode get_best_mode PROTO((int, int, int, enum machine_mode, int)); + +/* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT. */ + +#define GET_MODE_ALIGNMENT(MODE) \ + MIN (BIGGEST_ALIGNMENT, \ + MAX (1, (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT))) + +/* For each class, get the narrowest mode in that class. */ + +extern enum machine_mode class_narrowest_mode[]; +#define GET_CLASS_NARROWEST_MODE(CLASS) class_narrowest_mode[(int)(CLASS)] + +/* Define the integer modes whose sizes are BITS_PER_UNIT + and BITS_PER_WORD. */ + +extern enum machine_mode byte_mode; +extern enum machine_mode word_mode; + +#endif /* not HAVE_MACHINE_MODES */ diff --git a/gnu/usr.bin/cc/include/modemap.def b/gnu/usr.bin/cc/include/modemap.def new file mode 100644 index 0000000..3257640 --- /dev/null +++ b/gnu/usr.bin/cc/include/modemap.def @@ -0,0 +1,30 @@ +/* Bytecode specific machine mode info for GNU C-compiler. + Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Map mode to signed, unsigned typecodes, bytecode to push const, + to load, to store */ +DEF_MODEMAP(QImode, QIcode, QUcode, constQI, loadQI, storeQI) +DEF_MODEMAP(HImode, HIcode, HUcode, constHI, loadHI, storeHI) +DEF_MODEMAP(VOIDmode, SIcode, SUcode, constSI, loadSI, storeSI) +DEF_MODEMAP(SImode, SIcode, SUcode, constSI, loadSI, storeSI) +DEF_MODEMAP(DImode, DIcode, DUcode, constDI, loadDI, storeDI) +DEF_MODEMAP(PSImode, Pcode, Pcode, constP, loadP, storeP) +DEF_MODEMAP(BLKmode, Pcode, Pcode, constP, loadP, neverneverland) +DEF_MODEMAP(SFmode, SFcode, SFcode, constSF, loadSF, storeSF) +DEF_MODEMAP(DFmode, DFcode, DFcode, constDF, loadDF, storeDF) diff --git a/gnu/usr.bin/cc/include/multilib.h b/gnu/usr.bin/cc/include/multilib.h new file mode 100644 index 0000000..b2a5790 --- /dev/null +++ b/gnu/usr.bin/cc/include/multilib.h @@ -0,0 +1,3 @@ +#define MULTILIB_SELECT "\ +. ;\ +" diff --git a/gnu/usr.bin/cc/include/obstack.h b/gnu/usr.bin/cc/include/obstack.h new file mode 100644 index 0000000..0176719 --- /dev/null +++ b/gnu/usr.bin/cc/include/obstack.h @@ -0,0 +1,513 @@ +/* obstack.h - object stack macros + Copyright (C) 1988, 89, 90, 91, 92, 93, 94 Free Software Foundation, Inc. + +This program 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. + +This program 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; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Summary: + +All the apparent functions defined here are macros. The idea +is that you would use these pre-tested macros to solve a +very specific set of problems, and they would run fast. +Caution: no side-effects in arguments please!! They may be +evaluated MANY times!! + +These macros operate a stack of objects. Each object starts life +small, and may grow to maturity. (Consider building a word syllable +by syllable.) An object can move while it is growing. Once it has +been "finished" it never changes address again. So the "top of the +stack" is typically an immature growing object, while the rest of the +stack is of mature, fixed size and fixed address objects. + +These routines grab large chunks of memory, using a function you +supply, called `obstack_chunk_alloc'. On occasion, they free chunks, +by calling `obstack_chunk_free'. You must define them and declare +them before using any obstack macros. + +Each independent stack is represented by a `struct obstack'. +Each of the obstack macros expects a pointer to such a structure +as the first argument. + +One motivation for this package is the problem of growing char strings +in symbol tables. Unless you are "fascist pig with a read-only mind" +--Gosper's immortal quote from HAKMEM item 154, out of context--you +would not like to put any arbitrary upper limit on the length of your +symbols. + +In practice this often means you will build many short symbols and a +few long symbols. At the time you are reading a symbol you don't know +how long it is. One traditional method is to read a symbol into a +buffer, realloc()ating the buffer every time you try to read a symbol +that is longer than the buffer. This is beaut, but you still will +want to copy the symbol from the buffer to a more permanent +symbol-table entry say about half the time. + +With obstacks, you can work differently. Use one obstack for all symbol +names. As you read a symbol, grow the name in the obstack gradually. +When the name is complete, finalize it. Then, if the symbol exists already, +free the newly read name. + +The way we do this is to take a large chunk, allocating memory from +low addresses. When you want to build a symbol in the chunk you just +add chars above the current "high water mark" in the chunk. When you +have finished adding chars, because you got to the end of the symbol, +you know how long the chars are, and you can create a new object. +Mostly the chars will not burst over the highest address of the chunk, +because you would typically expect a chunk to be (say) 100 times as +long as an average object. + +In case that isn't clear, when we have enough chars to make up +the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) +so we just point to it where it lies. No moving of chars is +needed and this is the second win: potentially long strings need +never be explicitly shuffled. Once an object is formed, it does not +change its address during its lifetime. + +When the chars burst over a chunk boundary, we allocate a larger +chunk, and then copy the partly formed object from the end of the old +chunk to the beginning of the new larger chunk. We then carry on +accreting characters to the end of the object as we normally would. + +A special macro is provided to add a single char at a time to a +growing object. This allows the use of register variables, which +break the ordinary 'growth' macro. + +Summary: + We allocate large chunks. + We carve out one object at a time from the current chunk. + Once carved, an object never moves. + We are free to append data of any size to the currently + growing object. + Exactly one object is growing in an obstack at any one time. + You can run one obstack per control block. + You may have as many control blocks as you dare. + Because of the way we do it, you can `unwind' an obstack + back to a previous state. (You may remove objects much + as you would with a stack.) +*/ + + +/* Don't do the contents of this file more than once. */ + +#ifndef __OBSTACK_H__ +#define __OBSTACK_H__ + +/* We use subtraction of (char *)0 instead of casting to int + because on word-addressable machines a simple cast to int + may ignore the byte-within-word field of the pointer. */ + +#ifndef __PTR_TO_INT +#define __PTR_TO_INT(P) ((P) - (char *)0) +#endif + +#ifndef __INT_TO_PTR +#define __INT_TO_PTR(P) ((P) + (char *)0) +#endif + +/* We need the type of the resulting object. In ANSI C it is ptrdiff_t + but in traditional C it is usually long. If we are in ANSI C and + don't already have ptrdiff_t get it. */ + +#if defined (__STDC__) && ! defined (offsetof) +#if defined (__GNUC__) && defined (IN_GCC) +/* On Next machine, the system's stddef.h screws up if included + after we have defined just ptrdiff_t, so include all of stddef.h. + Otherwise, define just ptrdiff_t, which is all we need. */ +#ifndef __NeXT__ +#define __need_ptrdiff_t +#endif +#endif + +#include <stddef.h> +#endif + +#ifdef __STDC__ +#define PTR_INT_TYPE ptrdiff_t +#else +#define PTR_INT_TYPE long +#endif + +struct _obstack_chunk /* Lives at front of each chunk. */ +{ + char *limit; /* 1 past end of this chunk */ + struct _obstack_chunk *prev; /* address of prior chunk or NULL */ + char contents[4]; /* objects begin here */ +}; + +struct obstack /* control current object in current chunk */ +{ + long chunk_size; /* preferred size to allocate chunks in */ + struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */ + char *object_base; /* address of object we are building */ + char *next_free; /* where to add next char to current object */ + char *chunk_limit; /* address of char after current chunk */ + PTR_INT_TYPE temp; /* Temporary for some macros. */ + int alignment_mask; /* Mask of alignment for each object. */ + struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ + void (*freefun) (); /* User's function to free a chunk. */ + char *extra_arg; /* first arg for chunk alloc/dealloc funcs */ + unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */ + unsigned maybe_empty_object:1;/* There is a possibility that the current + chunk contains a zero-length object. This + prevents freeing the chunk if we allocate + a bigger chunk to replace it. */ + unsigned alloc_failed:1; /* chunk alloc func returned 0 */ +}; + +/* Declare the external functions we use; they are in obstack.c. */ + +#ifdef __STDC__ +extern void _obstack_newchunk (struct obstack *, int); +extern void _obstack_free (struct obstack *, void *); +extern int _obstack_begin (struct obstack *, int, int, + void *(*) (), void (*) ()); +extern int _obstack_begin_1 (struct obstack *, int, int, + void *(*) (), void (*) (), void *); +#else +extern void _obstack_newchunk (); +extern void _obstack_free (); +extern int _obstack_begin (); +extern int _obstack_begin_1 (); +#endif + +#ifdef __STDC__ + +/* Do the function-declarations after the structs + but before defining the macros. */ + +void obstack_init (struct obstack *obstack); + +void * obstack_alloc (struct obstack *obstack, int size); + +void * obstack_copy (struct obstack *obstack, void *address, int size); +void * obstack_copy0 (struct obstack *obstack, void *address, int size); + +void obstack_free (struct obstack *obstack, void *block); + +void obstack_blank (struct obstack *obstack, int size); + +void obstack_grow (struct obstack *obstack, void *data, int size); +void obstack_grow0 (struct obstack *obstack, void *data, int size); + +void obstack_1grow (struct obstack *obstack, int data_char); +void obstack_ptr_grow (struct obstack *obstack, void *data); +void obstack_int_grow (struct obstack *obstack, int data); + +void * obstack_finish (struct obstack *obstack); + +int obstack_object_size (struct obstack *obstack); + +int obstack_room (struct obstack *obstack); +void obstack_1grow_fast (struct obstack *obstack, int data_char); +void obstack_ptr_grow_fast (struct obstack *obstack, void *data); +void obstack_int_grow_fast (struct obstack *obstack, int data); +void obstack_blank_fast (struct obstack *obstack, int size); + +void * obstack_base (struct obstack *obstack); +void * obstack_next_free (struct obstack *obstack); +int obstack_alignment_mask (struct obstack *obstack); +int obstack_chunk_size (struct obstack *obstack); + +#endif /* __STDC__ */ + +/* Non-ANSI C cannot really support alternative functions for these macros, + so we do not declare them. */ + +/* Pointer to beginning of object being allocated or to be allocated next. + Note that this might not be the final address of the object + because a new chunk might be needed to hold the final size. */ + +#define obstack_base(h) ((h)->alloc_failed ? 0 : (h)->object_base) + +/* Size for allocating ordinary chunks. */ + +#define obstack_chunk_size(h) ((h)->chunk_size) + +/* Pointer to next byte not yet allocated in current chunk. */ + +#define obstack_next_free(h) ((h)->alloc_failed ? 0 : (h)->next_free) + +/* Mask specifying low bits that should be clear in address of an object. */ + +#define obstack_alignment_mask(h) ((h)->alignment_mask) + +#define obstack_init(h) \ + _obstack_begin ((h), 0, 0, \ + (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) + +#define obstack_begin(h, size) \ + _obstack_begin ((h), (size), 0, \ + (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free) + +#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \ + _obstack_begin ((h), (size), (alignment), \ + (void *(*) ()) (chunkfun), (void (*) ()) (freefun)) + +#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \ + _obstack_begin_1 ((h), (size), (alignment), \ + (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg)) + +#define obstack_chunkfun(h, newchunkfun) \ + ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun)) + +#define obstack_freefun(h, newfreefun) \ + ((h) -> freefun = (void (*)()) (newfreefun)) + +#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar) + +#define obstack_blank_fast(h,n) ((h)->next_free += (n)) + +#if defined (__GNUC__) && defined (__STDC__) +#if __GNUC__ < 2 +#define __extension__ +#endif + +/* For GNU C, if not -traditional, + we can define these macros to compute all args only once + without using a global variable. + Also, we can avoid using the `temp' slot, to make faster code. */ + +#define obstack_object_size(OBSTACK) \ + __extension__ \ + ({ struct obstack *__o = (OBSTACK); \ + __o->alloc_failed ? 0 : \ + (unsigned) (__o->next_free - __o->object_base); }) + +#define obstack_room(OBSTACK) \ + __extension__ \ + ({ struct obstack *__o = (OBSTACK); \ + (unsigned) (__o->chunk_limit - __o->next_free); }) + +#define obstack_grow(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->next_free + __len > __o->chunk_limit) \ + _obstack_newchunk (__o, __len); \ + if (!__o->alloc_failed) \ + { \ + bcopy ((char *) (where), __o->next_free, __len); \ + __o->next_free += __len; \ + } \ + (void) 0; }) + +#define obstack_grow0(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->next_free + __len + 1 > __o->chunk_limit) \ + _obstack_newchunk (__o, __len + 1); \ + if (!__o->alloc_failed) \ + { \ + bcopy ((char *) (where), __o->next_free, __len); \ + __o->next_free += __len; \ + *(__o->next_free)++ = 0; \ + } \ + (void) 0; }) + +#define obstack_1grow(OBSTACK,datum) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + 1 > __o->chunk_limit) \ + _obstack_newchunk (__o, 1); \ + if (!__o->alloc_failed) \ + *(__o->next_free)++ = (datum); \ + (void) 0; }) + +/* These assume that the obstack alignment is good enough for pointers or ints, + and that the data added so far to the current object + shares that much alignment. */ + +#define obstack_ptr_grow(OBSTACK,datum) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + sizeof (void *) > __o->chunk_limit) \ + _obstack_newchunk (__o, sizeof (void *)); \ + if (!__o->alloc_failed) \ + *((void **)__o->next_free)++ = ((void *)datum); \ + (void) 0; }) + +#define obstack_int_grow(OBSTACK,datum) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + if (__o->next_free + sizeof (int) > __o->chunk_limit) \ + _obstack_newchunk (__o, sizeof (int)); \ + if (!__o->alloc_failed) \ + *((int *)__o->next_free)++ = ((int)datum); \ + (void) 0; }) + +#define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr) +#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint) + +#define obstack_blank(OBSTACK,length) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + if (__o->chunk_limit - __o->next_free < __len) \ + _obstack_newchunk (__o, __len); \ + if (!__o->alloc_failed) \ + __o->next_free += __len; \ + (void) 0; }) + +#define obstack_alloc(OBSTACK,length) \ +__extension__ \ +({ struct obstack *__h = (OBSTACK); \ + obstack_blank (__h, (length)); \ + obstack_finish (__h); }) + +#define obstack_copy(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__h = (OBSTACK); \ + obstack_grow (__h, (where), (length)); \ + obstack_finish (__h); }) + +#define obstack_copy0(OBSTACK,where,length) \ +__extension__ \ +({ struct obstack *__h = (OBSTACK); \ + obstack_grow0 (__h, (where), (length)); \ + obstack_finish (__h); }) + +/* The local variable is named __o1 to avoid a name conflict + when obstack_blank is called. */ +#define obstack_finish(OBSTACK) \ +__extension__ \ +({ struct obstack *__o1 = (OBSTACK); \ + void *value; \ + if (__o1->alloc_failed) \ + value = 0; \ + else \ + { \ + value = (void *) __o1->object_base; \ + if (__o1->next_free == value) \ + __o1->maybe_empty_object = 1; \ + __o1->next_free \ + = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\ + & ~ (__o1->alignment_mask)); \ + if (__o1->next_free - (char *)__o1->chunk \ + > __o1->chunk_limit - (char *)__o1->chunk) \ + __o1->next_free = __o1->chunk_limit; \ + __o1->object_base = __o1->next_free; \ + } \ + value; }) + +#define obstack_free(OBSTACK, OBJ) \ +__extension__ \ +({ struct obstack *__o = (OBSTACK); \ + void *__obj = (OBJ); \ + if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ + __o->next_free = __o->object_base = __obj; \ + else (obstack_free) (__o, __obj); }) + +#else /* not __GNUC__ or not __STDC__ */ + +#define obstack_object_size(h) \ + (unsigned) ((h)->alloc_failed ? 0 : (h)->next_free - (h)->object_base) + +#define obstack_room(h) \ + (unsigned) ((h)->chunk_limit - (h)->next_free) + +/* Note that the call to _obstack_newchunk is enclosed in (..., 0) + so that we can avoid having void expressions + in the arms of the conditional expression. + Casting the third operand to void was tried before, + but some compilers won't accept it. */ + +#define obstack_grow(h,where,length) \ +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ + ((h)->alloc_failed ? 0 : \ + (bcopy ((char *) (where), (h)->next_free, (h)->temp), \ + (h)->next_free += (h)->temp))) + +#define obstack_grow0(h,where,length) \ +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \ + ((h)->alloc_failed ? 0 : \ + (bcopy ((char *) (where), (h)->next_free, (h)->temp), \ + (h)->next_free += (h)->temp, \ + *((h)->next_free)++ = 0))) + +#define obstack_1grow(h,datum) \ +( (((h)->next_free + 1 > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), 1), 0) : 0), \ + ((h)->alloc_failed ? 0 : \ + (*((h)->next_free)++ = (datum)))) + +#define obstack_ptr_grow(h,datum) \ +( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \ + ((h)->alloc_failed ? 0 : \ + (*((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum)))) + +#define obstack_int_grow(h,datum) \ +( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \ + ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \ + ((h)->alloc_failed ? 0 : \ + (*((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum)))) + +#define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr) +#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint) + +#define obstack_blank(h,length) \ +( (h)->temp = (length), \ + (((h)->chunk_limit - (h)->next_free < (h)->temp) \ + ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \ + ((h)->alloc_failed ? 0 : \ + ((h)->next_free += (h)->temp))) + +#define obstack_alloc(h,length) \ + (obstack_blank ((h), (length)), obstack_finish ((h))) + +#define obstack_copy(h,where,length) \ + (obstack_grow ((h), (where), (length)), obstack_finish ((h))) + +#define obstack_copy0(h,where,length) \ + (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) + +#define obstack_finish(h) \ +( (h)->alloc_failed ? 0 : \ + (((h)->next_free == (h)->object_base \ + ? (((h)->maybe_empty_object = 1), 0) \ + : 0), \ + (h)->temp = __PTR_TO_INT ((h)->object_base), \ + (h)->next_free \ + = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \ + & ~ ((h)->alignment_mask)), \ + (((h)->next_free - (char *)(h)->chunk \ + > (h)->chunk_limit - (char *)(h)->chunk) \ + ? ((h)->next_free = (h)->chunk_limit) : 0), \ + (h)->object_base = (h)->next_free, \ + __INT_TO_PTR ((h)->temp))) + +#ifdef __STDC__ +#define obstack_free(h,obj) \ +( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ + (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ + ? (int) ((h)->next_free = (h)->object_base \ + = (h)->temp + (char *) (h)->chunk) \ + : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0))) +#else +#define obstack_free(h,obj) \ +( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ + (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ + ? (int) ((h)->next_free = (h)->object_base \ + = (h)->temp + (char *) (h)->chunk) \ + : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0))) +#endif + +#endif /* not __GNUC__ or not __STDC__ */ + +#endif /* not __OBSTACK_H__ */ diff --git a/gnu/usr.bin/cc/include/output.h b/gnu/usr.bin/cc/include/output.h new file mode 100644 index 0000000..ebd0a2f --- /dev/null +++ b/gnu/usr.bin/cc/include/output.h @@ -0,0 +1,241 @@ +/* Declarations for insn-output.c. These functions are defined in recog.c, + final.c, and varasm.c. + Copyright (C) 1987, 1991, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Initialize data in final at the beginning of a compilation. */ +extern void init_final PROTO((char *)); + +/* Called at end of source file, + to output the block-profiling table for this entire compilation. */ +extern void end_final PROTO((char *)); + +/* Enable APP processing of subsequent output. + Used before the output from an `asm' statement. */ +extern void app_enable PROTO((void)); + +/* Disable APP processing of subsequent output. + Called from varasm.c before most kinds of output. */ +extern void app_disable PROTO((void)); + +/* Return the number of slots filled in the current + delayed branch sequence (we don't count the insn needing the + delay slot). Zero if not in a delayed branch sequence. */ +extern int dbr_sequence_length PROTO((void)); + +/* Indicate that branch shortening hasn't yet been done. */ +extern void init_insn_lengths PROTO((void)); + +/* Obtain the current length of an insn. If branch shortening has been done, + get its actual length. Otherwise, get its maximum length. */ +extern int get_attr_length PROTO((rtx)); + +/* Make a pass over all insns and compute their actual lengths by shortening + any branches of variable length if possible. */ +extern void shorten_branches PROTO((rtx)); + +/* Output assembler code for the start of a function, + and initialize some of the variables in this file + for the new function. The label for the function and associated + assembler pseudo-ops have already been output in + `assemble_start_function'. */ +extern void final_start_function STDIO_PROTO((rtx, FILE *, int)); + +/* Output assembler code for the end of a function. + For clarity, args are same as those of `final_start_function' + even though not all of them are needed. */ +extern void final_end_function STDIO_PROTO((rtx, FILE *, int)); + +/* Output assembler code for some insns: all or part of a function. */ +extern void final STDIO_PROTO((rtx, FILE *, int, int)); + +/* The final scan for one insn, INSN. Args are same as in `final', except + that INSN is the insn being scanned. Value returned is the next insn to + be scanned. */ +extern rtx final_scan_insn STDIO_PROTO((rtx, FILE *, int, int, int)); + +/* Replace a SUBREG with a REG or a MEM, based on the thing it is a + subreg of. */ +extern rtx alter_subreg PROTO((rtx)); + +/* Report inconsistency between the assembler template and the operands. + In an `asm', it's the user's fault; otherwise, the compiler's fault. */ +extern void output_operand_lossage PROTO((char *)); + +/* Output a string of assembler code, substituting insn operands. + Defined in final.c. */ +extern void output_asm_insn PROTO((char *, rtx *)); + +/* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol. */ +extern void output_asm_label PROTO((rtx)); + +/* Print a memory reference operand for address X + using machine-dependent assembler syntax. */ +extern void output_address PROTO((rtx)); + +/* Print an integer constant expression in assembler syntax. + Addition and subtraction are the only arithmetic + that may appear in these expressions. */ +extern void output_addr_const STDIO_PROTO((FILE *, rtx)); + +/* Output a string of assembler code, substituting numbers, strings + and fixed syntactic prefixes. */ +extern void asm_fprintf STDIO_PROTO(PVPROTO((FILE *file, + char *p, ...))); + +/* Split up a CONST_DOUBLE or integer constant rtx into two rtx's for single + words. */ +extern void split_double PROTO((rtx, rtx *, rtx *)); + +/* Return nonzero if this function has no function calls. */ +extern int leaf_function_p PROTO((void)); + +/* Return 1 if this function uses only the registers that can be + safely renumbered. */ +extern int only_leaf_regs_used PROTO((void)); + +/* Scan IN_RTX and its subexpressions, and renumber all regs into those + available in leaf functions. */ +extern void leaf_renumber_regs_insn PROTO((rtx)); + +/* Output a name (as found inside a symbol_ref) in assembler syntax. */ +extern void assemble_name STDIO_PROTO((FILE *, char *)); + +/* When outputting assembler code, indicates which alternative + of the constraints was actually satisfied. */ +extern int which_alternative; + +/* When outputting delayed branch sequences, this rtx holds the + sequence being output. It is null when no delayed branch + sequence is being output, so it can be used as a test in the + insn output code. + + This variable is defined in final.c. */ +extern rtx final_sequence; + +/* Number of bytes of args popped by function being compiled on its return. + Zero if no bytes are to be popped. + May affect compilation of return insn or of function epilogue. */ + +extern int current_function_pops_args; + +/* Nonzero if function being compiled needs to be given an address + where the value should be stored. */ + +extern int current_function_returns_struct; + +/* Nonzero if function being compiled needs to + return the address of where it has put a structure value. */ + +extern int current_function_returns_pcc_struct; + +/* Nonzero if function being compiled needs to be passed a static chain. */ + +extern int current_function_needs_context; + +/* Nonzero if function being compiled can call setjmp. */ + +extern int current_function_calls_setjmp; + +/* Nonzero if function being compiled can call longjmp. */ + +extern int current_function_calls_longjmp; + +/* Nonzero if function being compiled can call alloca, + either as a subroutine or builtin. */ + +extern int current_function_calls_alloca; + +/* Nonzero if function being compiled receives nonlocal gotos + from nested functions. */ + +extern int current_function_has_nonlocal_label; + +/* Nonzero if function being compiled contains nested functions. */ + +extern int current_function_contains_functions; + +/* Nonzero if the current function returns a pointer type */ + +extern int current_function_returns_pointer; + +/* If function's args have a fixed size, this is that size, in bytes. + Otherwise, it is -1. + May affect compilation of return insn or of function epilogue. */ + +extern int current_function_args_size; + +/* # bytes the prologue should push and pretend that the caller pushed them. + The prologue must do this, but only if parms can be passed in registers. */ + +extern int current_function_pretend_args_size; + +/* # of bytes of outgoing arguments required to be pushed by the prologue. + If this is non-zero, it means that ACCUMULATE_OUTGOING_ARGS was defined + and no stack adjusts will be done on function calls. */ + +extern int current_function_outgoing_args_size; + +/* Nonzero if current function uses varargs.h or equivalent. + Zero for functions that use stdarg.h. */ + +extern int current_function_varargs; + +/* Quantities of various kinds of registers + used for the current function's args. */ + +extern CUMULATIVE_ARGS current_function_args_info; + +/* Name of function now being compiled. */ + +extern char *current_function_name; + +/* If non-zero, an RTL expression for that location at which the current + function returns its result. Usually equal to + DECL_RTL (DECL_RESULT (current_function_decl)). */ + +extern rtx current_function_return_rtx; + +/* If some insns can be deferred to the delay slots of the epilogue, the + delay list for them is recorded here. */ + +extern rtx current_function_epilogue_delay_list; + +/* Nonzero means generate position-independent code. + This is not fully implemented yet. */ + +extern int flag_pic; + +/* This is nonzero if the current function uses pic_offset_table_rtx. */ +extern int current_function_uses_pic_offset_table; + +/* This is nonzero if the current function uses the constant pool. */ +extern int current_function_uses_const_pool; + +/* The line number of the beginning of the current function. + sdbout.c needs this so that it can output relative linenumbers. */ + +#ifdef SDB_DEBUGGING_INFO /* Avoid undef sym in certain broken linkers. */ +extern int sdb_begin_function_line; +#endif + +/* File in which assembler code is being written. */ + +#ifdef BUFSIZ +extern FILE *asm_out_file; +#endif diff --git a/gnu/usr.bin/cc/include/pcp.h b/gnu/usr.bin/cc/include/pcp.h new file mode 100644 index 0000000..0b86a87 --- /dev/null +++ b/gnu/usr.bin/cc/include/pcp.h @@ -0,0 +1,100 @@ +/* pcp.h -- Describes the format of a precompiled file + Copyright (C) 1990 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + +/* Structure allocated for every string in a precompiled file */ +typedef struct stringdef STRINGDEF; +struct stringdef +{ + U_CHAR *contents; /* String to include */ + int len; /* Its length */ + int writeflag; /* Whether we write this */ + int lineno; /* Linenumber of source file */ + U_CHAR *filename; /* Name of source file */ + STRINGDEF *chain; /* Global list of strings in natural order */ + int output_mark; /* Where in the output this goes */ +}; + +typedef struct keydef KEYDEF; +struct keydef +{ + STRINGDEF *str; + KEYDEF *chain; +}; + +/* Format: */ +/* A precompiled file starts with a series of #define and #undef + statements: + #define MAC DEF --- Indicates MAC must be defined with defn DEF + #define MAC --- Indicates MAC must be defined with any defn + #undef MAC --- Indicates MAC cannot be defined + +These preconditions must be true for a precompiled file to be used. +The preconditions section is null terminated. */ + +/* Then, there is a four byte number (in network byte order) which */ + /* indicates the number of strings the file contains. */ + +/* Each string contains a STRINGDEF structure. The only component of */ + /* the STRINGDEF structure which is used is the lineno field, which */ + /* should hold the line number in the original header file. */ + /* Then follows the string, followed by a null. Then comes a four */ + /* byte number (again, in network byte order) indicating the number */ + /* of keys for this string. Each key is a KEYDEF structure, with */ + /* irrelevant contents, followed by the null-terminated string. */ + +/* If the number of keys is 0, then there are no keys for the string, */ + /* in other words, the string will never be included. If the number */ + /* of keys is -1, this is a special flag indicating there are no keys */ + /* in the file, and the string is mandatory (that is, it must be */ + /* included regardless in the included output). */ + +/* A file, then, looks like this: + + Precondition 1 + Precondition 2 + . + . + . + <NUL> + Number of strings + STRINGDEF + String . . . <NUL> + Number of keys + KEYDEF + Key . . . <NUL> + KEYDEF + Key . . . <NUL> + . + . + . + STRINGDEF + String . . . <NUL> + Number of keys + KEYDEF + Key . . . <NUL> + . + . + . + . + . + . + +*/ diff --git a/gnu/usr.bin/cc/include/real.h b/gnu/usr.bin/cc/include/real.h new file mode 100644 index 0000000..34d6d67 --- /dev/null +++ b/gnu/usr.bin/cc/include/real.h @@ -0,0 +1,437 @@ +/* Front-end tree definitions for GNU compiler. + Copyright (C) 1989, 1991, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef REAL_H_INCLUDED +#define REAL_H_INCLUDED + +/* Define codes for all the float formats that we know of. */ +#define UNKNOWN_FLOAT_FORMAT 0 +#define IEEE_FLOAT_FORMAT 1 +#define VAX_FLOAT_FORMAT 2 +#define IBM_FLOAT_FORMAT 3 + +/* Default to IEEE float if not specified. Nearly all machines use it. */ + +#ifndef TARGET_FLOAT_FORMAT +#define TARGET_FLOAT_FORMAT IEEE_FLOAT_FORMAT +#endif + +#ifndef HOST_FLOAT_FORMAT +#define HOST_FLOAT_FORMAT IEEE_FLOAT_FORMAT +#endif + +#if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT +#define REAL_INFINITY +#endif + +/* If FLOAT_WORDS_BIG_ENDIAN and HOST_FLOAT_WORDS_BIG_ENDIAN are not defined + in the header files, then this implies the word-endianness is the same as + for integers. */ + +/* This is defined 0 or 1, like WORDS_BIG_ENDIAN. */ +#ifndef FLOAT_WORDS_BIG_ENDIAN +#define FLOAT_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN +#endif + +/* This is defined 0 or 1, unlike HOST_WORDS_BIG_ENDIAN. */ +#ifndef HOST_FLOAT_WORDS_BIG_ENDIAN +#ifdef HOST_WORDS_BIG_ENDIAN +#define HOST_FLOAT_WORDS_BIG_ENDIAN 1 +#else +#define HOST_FLOAT_WORDS_BIG_ENDIAN 0 +#endif +#endif + +/* Defining REAL_ARITHMETIC invokes a floating point emulator + that can produce a target machine format differing by more + than just endian-ness from the host's format. The emulator + is also used to support extended real XFmode. */ +#ifndef LONG_DOUBLE_TYPE_SIZE +#define LONG_DOUBLE_TYPE_SIZE 64 +#endif +#if (LONG_DOUBLE_TYPE_SIZE == 96) || (LONG_DOUBLE_TYPE_SIZE == 128) +#ifndef REAL_ARITHMETIC +#define REAL_ARITHMETIC +#endif +#endif +#ifdef REAL_ARITHMETIC +/* **** Start of software floating point emulator interface macros **** */ + +/* Support 80-bit extended real XFmode if LONG_DOUBLE_TYPE_SIZE + has been defined to be 96 in the tm.h machine file. */ +#if (LONG_DOUBLE_TYPE_SIZE == 96) +#define REAL_IS_NOT_DOUBLE +#define REAL_ARITHMETIC +typedef struct { + HOST_WIDE_INT r[(11 + sizeof (HOST_WIDE_INT))/(sizeof (HOST_WIDE_INT))]; +} realvaluetype; +#define REAL_VALUE_TYPE realvaluetype + +#else /* no XFmode support */ + +#if (LONG_DOUBLE_TYPE_SIZE == 128) + +#define REAL_IS_NOT_DOUBLE +#define REAL_ARITHMETIC +typedef struct { + HOST_WIDE_INT r[(19 + sizeof (HOST_WIDE_INT))/(sizeof (HOST_WIDE_INT))]; +} realvaluetype; +#define REAL_VALUE_TYPE realvaluetype + +#else /* not TFmode */ + +#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT +/* If no XFmode support, then a REAL_VALUE_TYPE is 64 bits wide + but it is not necessarily a host machine double. */ +#define REAL_IS_NOT_DOUBLE +typedef struct { + HOST_WIDE_INT r[(7 + sizeof (HOST_WIDE_INT))/(sizeof (HOST_WIDE_INT))]; +} realvaluetype; +#define REAL_VALUE_TYPE realvaluetype +#else +/* If host and target formats are compatible, then a REAL_VALUE_TYPE + is actually a host machine double. */ +#define REAL_VALUE_TYPE double +#endif + +#endif /* no TFmode support */ +#endif /* no XFmode support */ + +extern int significand_size PROTO((enum machine_mode)); + +/* If emulation has been enabled by defining REAL_ARITHMETIC or by + setting LONG_DOUBLE_TYPE_SIZE to 96 or 128, then define macros so that + they invoke emulator functions. This will succeed only if the machine + files have been updated to use these macros in place of any + references to host machine `double' or `float' types. */ +#ifdef REAL_ARITHMETIC +#undef REAL_ARITHMETIC +#define REAL_ARITHMETIC(value, code, d1, d2) \ + earith (&(value), (code), &(d1), &(d2)) + +/* Declare functions in real.c. */ +extern void earith PROTO((REAL_VALUE_TYPE *, int, + REAL_VALUE_TYPE *, REAL_VALUE_TYPE *)); +extern REAL_VALUE_TYPE etrunci PROTO((REAL_VALUE_TYPE)); +extern REAL_VALUE_TYPE etruncui PROTO((REAL_VALUE_TYPE)); +extern REAL_VALUE_TYPE ereal_atof PROTO((char *, enum machine_mode)); +extern REAL_VALUE_TYPE ereal_negate PROTO((REAL_VALUE_TYPE)); +extern HOST_WIDE_INT efixi PROTO((REAL_VALUE_TYPE)); +extern unsigned HOST_WIDE_INT efixui PROTO((REAL_VALUE_TYPE)); +extern void ereal_from_int PROTO((REAL_VALUE_TYPE *, + HOST_WIDE_INT, HOST_WIDE_INT)); +extern void ereal_from_uint PROTO((REAL_VALUE_TYPE *, + unsigned HOST_WIDE_INT, + unsigned HOST_WIDE_INT)); +extern void ereal_to_int PROTO((HOST_WIDE_INT *, HOST_WIDE_INT *, + REAL_VALUE_TYPE)); +extern REAL_VALUE_TYPE ereal_ldexp PROTO((REAL_VALUE_TYPE, int)); + +extern void etartdouble PROTO((REAL_VALUE_TYPE, long *)); +extern void etarldouble PROTO((REAL_VALUE_TYPE, long *)); +extern void etardouble PROTO((REAL_VALUE_TYPE, long *)); +extern long etarsingle PROTO((REAL_VALUE_TYPE)); +extern void ereal_to_decimal PROTO((REAL_VALUE_TYPE, char *)); +extern int ereal_cmp PROTO((REAL_VALUE_TYPE, REAL_VALUE_TYPE)); +extern int ereal_isneg PROTO((REAL_VALUE_TYPE)); +extern REAL_VALUE_TYPE ereal_from_float PROTO((HOST_WIDE_INT)); +extern REAL_VALUE_TYPE ereal_from_double PROTO((HOST_WIDE_INT *)); + +#define REAL_VALUES_EQUAL(x, y) (ereal_cmp ((x), (y)) == 0) +/* true if x < y : */ +#define REAL_VALUES_LESS(x, y) (ereal_cmp ((x), (y)) == -1) +#define REAL_VALUE_LDEXP(x, n) ereal_ldexp (x, n) + +/* These return REAL_VALUE_TYPE: */ +#define REAL_VALUE_RNDZINT(x) (etrunci (x)) +#define REAL_VALUE_UNSIGNED_RNDZINT(x) (etruncui (x)) +extern REAL_VALUE_TYPE real_value_truncate (); +#define REAL_VALUE_TRUNCATE(mode, x) real_value_truncate (mode, x) + +/* These return HOST_WIDE_INT: */ +/* Convert a floating-point value to integer, rounding toward zero. */ +#define REAL_VALUE_FIX(x) (efixi (x)) +/* Convert a floating-point value to unsigned integer, rounding + toward zero. */ +#define REAL_VALUE_UNSIGNED_FIX(x) (efixui (x)) + +#define REAL_VALUE_ATOF ereal_atof +#define REAL_VALUE_NEGATE ereal_negate + +#define REAL_VALUE_MINUS_ZERO(x) \ + ((ereal_cmp (x, dconst0) == 0) && (ereal_isneg (x) != 0 )) + +#define REAL_VALUE_TO_INT ereal_to_int + +/* Here the cast to HOST_WIDE_INT sign-extends arguments such as ~0. */ +#define REAL_VALUE_FROM_INT(d, lo, hi) \ + ereal_from_int (&d, (HOST_WIDE_INT) (lo), (HOST_WIDE_INT) (hi)) + +#define REAL_VALUE_FROM_UNSIGNED_INT(d, lo, hi) (ereal_from_uint (&d, lo, hi)) + +/* IN is a REAL_VALUE_TYPE. OUT is an array of longs. */ +#if LONG_DOUBLE_TYPE_SIZE == 96 +#define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT) (etarldouble ((IN), (OUT))) +#else +#define REAL_VALUE_TO_TARGET_LONG_DOUBLE(IN, OUT) (etartdouble ((IN), (OUT))) +#endif +#define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) (etardouble ((IN), (OUT))) + +/* IN is a REAL_VALUE_TYPE. OUT is a long. */ +#define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) ((OUT) = etarsingle ((IN))) + +/* d is an array of HOST_WIDE_INT that holds a double precision + value in the target computer's floating point format. */ +#define REAL_VALUE_FROM_TARGET_DOUBLE(d) (ereal_from_double (d)) + +/* f is a HOST_WIDE_INT containing a single precision target float value. */ +#define REAL_VALUE_FROM_TARGET_SINGLE(f) (ereal_from_float (f)) + +/* Conversions to decimal ASCII string. */ +#define REAL_VALUE_TO_DECIMAL(r, fmt, s) (ereal_to_decimal (r, s)) + +#endif /* REAL_ARITHMETIC defined */ + +/* **** End of software floating point emulator interface macros **** */ +#else /* No XFmode or TFmode and REAL_ARITHMETIC not defined */ + +/* old interface */ +#ifdef REAL_ARITHMETIC +/* Defining REAL_IS_NOT_DOUBLE breaks certain initializations + when REAL_ARITHMETIC etc. are not defined. */ + +/* Now see if the host and target machines use the same format. + If not, define REAL_IS_NOT_DOUBLE (even if we end up representing + reals as doubles because we have no better way in this cross compiler.) + This turns off various optimizations that can happen when we know the + compiler's float format matches the target's float format. + */ +#if HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT +#define REAL_IS_NOT_DOUBLE +#ifndef REAL_VALUE_TYPE +typedef struct { + HOST_WIDE_INT r[sizeof (double)/sizeof (HOST_WIDE_INT)]; + } realvaluetype; +#define REAL_VALUE_TYPE realvaluetype +#endif /* no REAL_VALUE_TYPE */ +#endif /* formats differ */ +#endif /* 0 */ + +#endif /* emulator not used */ + +/* If we are not cross-compiling, use a `double' to represent the + floating-point value. Otherwise, use some other type + (probably a struct containing an array of longs). */ +#ifndef REAL_VALUE_TYPE +#define REAL_VALUE_TYPE double +#else +#define REAL_IS_NOT_DOUBLE +#endif + +#if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT + +/* Convert a type `double' value in host format first to a type `float' + value in host format and then to a single type `long' value which + is the bitwise equivalent of the `float' value. */ +#ifndef REAL_VALUE_TO_TARGET_SINGLE +#define REAL_VALUE_TO_TARGET_SINGLE(IN, OUT) \ +do { float f = (float) (IN); \ + (OUT) = *(long *) &f; \ + } while (0) +#endif + +/* Convert a type `double' value in host format to a pair of type `long' + values which is its bitwise equivalent, but put the two words into + proper word order for the target. */ +#ifndef REAL_VALUE_TO_TARGET_DOUBLE +#if HOST_FLOAT_WORDS_BIG_ENDIAN == FLOAT_WORDS_BIG_ENDIAN +#define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \ +do { REAL_VALUE_TYPE in = (IN); /* Make sure it's not in a register. */\ + (OUT)[0] = ((long *) &in)[0]; \ + (OUT)[1] = ((long *) &in)[1]; \ + } while (0) +#else +#define REAL_VALUE_TO_TARGET_DOUBLE(IN, OUT) \ +do { REAL_VALUE_TYPE in = (IN); /* Make sure it's not in a register. */\ + (OUT)[1] = ((long *) &in)[0]; \ + (OUT)[0] = ((long *) &in)[1]; \ + } while (0) +#endif +#endif +#endif /* HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT */ + +/* In this configuration, double and long double are the same. */ +#ifndef REAL_VALUE_TO_TARGET_LONG_DOUBLE +#define REAL_VALUE_TO_TARGET_LONG_DOUBLE(a, b) REAL_VALUE_TO_TARGET_DOUBLE (a, b) +#endif + +/* Compare two floating-point values for equality. */ +#ifndef REAL_VALUES_EQUAL +#define REAL_VALUES_EQUAL(x, y) ((x) == (y)) +#endif + +/* Compare two floating-point values for less than. */ +#ifndef REAL_VALUES_LESS +#define REAL_VALUES_LESS(x, y) ((x) < (y)) +#endif + +/* Truncate toward zero to an integer floating-point value. */ +#ifndef REAL_VALUE_RNDZINT +#define REAL_VALUE_RNDZINT(x) ((double) ((int) (x))) +#endif + +/* Truncate toward zero to an unsigned integer floating-point value. */ +#ifndef REAL_VALUE_UNSIGNED_RNDZINT +#define REAL_VALUE_UNSIGNED_RNDZINT(x) ((double) ((unsigned int) (x))) +#endif + +/* Convert a floating-point value to integer, rounding toward zero. */ +#ifndef REAL_VALUE_FIX +#define REAL_VALUE_FIX(x) ((int) (x)) +#endif + +/* Convert a floating-point value to unsigned integer, rounding + toward zero. */ +#ifndef REAL_VALUE_UNSIGNED_FIX +#define REAL_VALUE_UNSIGNED_FIX(x) ((unsigned int) (x)) +#endif + +/* Scale X by Y powers of 2. */ +#ifndef REAL_VALUE_LDEXP +#define REAL_VALUE_LDEXP(x, y) ldexp (x, y) +extern double ldexp (); +#endif + +/* Convert the string X to a floating-point value. */ +#ifndef REAL_VALUE_ATOF +#if 1 +/* Use real.c to convert decimal numbers to binary, ... */ +REAL_VALUE_TYPE ereal_atof (); +#define REAL_VALUE_ATOF(x, s) ereal_atof (x, s) +#else +/* ... or, if you like the host computer's atof, go ahead and use it: */ +#define REAL_VALUE_ATOF(x, s) atof (x) +#if defined (MIPSEL) || defined (MIPSEB) +/* MIPS compiler can't handle parens around the function name. + This problem *does not* appear to be connected with any + macro definition for atof. It does not seem there is one. */ +extern double atof (); +#else +extern double (atof) (); +#endif +#endif +#endif + +/* Negate the floating-point value X. */ +#ifndef REAL_VALUE_NEGATE +#define REAL_VALUE_NEGATE(x) (- (x)) +#endif + +/* Truncate the floating-point value X to mode MODE. This is correct only + for the most common case where the host and target have objects of the same + size and where `float' is SFmode. */ + +/* Don't use REAL_VALUE_TRUNCATE directly--always call real_value_truncate. */ +extern REAL_VALUE_TYPE real_value_truncate (); + +#ifndef REAL_VALUE_TRUNCATE +#define REAL_VALUE_TRUNCATE(mode, x) \ + (GET_MODE_BITSIZE (mode) == sizeof (float) * HOST_BITS_PER_CHAR \ + ? (float) (x) : (x)) +#endif + +/* Determine whether a floating-point value X is infinite. */ +#ifndef REAL_VALUE_ISINF +#define REAL_VALUE_ISINF(x) (target_isinf (x)) +#endif + +/* Determine whether a floating-point value X is a NaN. */ +#ifndef REAL_VALUE_ISNAN +#define REAL_VALUE_ISNAN(x) (target_isnan (x)) +#endif + +/* Determine whether a floating-point value X is negative. */ +#ifndef REAL_VALUE_NEGATIVE +#define REAL_VALUE_NEGATIVE(x) (target_negative (x)) +#endif + +/* Determine whether a floating-point value X is minus 0. */ +#ifndef REAL_VALUE_MINUS_ZERO +#define REAL_VALUE_MINUS_ZERO(x) ((x) == 0 && REAL_VALUE_NEGATIVE (x)) +#endif + +/* Constant real values 0, 1, 2, and -1. */ + +extern REAL_VALUE_TYPE dconst0; +extern REAL_VALUE_TYPE dconst1; +extern REAL_VALUE_TYPE dconst2; +extern REAL_VALUE_TYPE dconstm1; + +/* Union type used for extracting real values from CONST_DOUBLEs + or putting them in. */ + +union real_extract +{ + REAL_VALUE_TYPE d; + HOST_WIDE_INT i[sizeof (REAL_VALUE_TYPE) / sizeof (HOST_WIDE_INT)]; +}; + +/* For a CONST_DOUBLE: + The usual two ints that hold the value. + For a DImode, that is all there are; + and CONST_DOUBLE_LOW is the low-order word and ..._HIGH the high-order. + For a float, the number of ints varies, + and CONST_DOUBLE_LOW is the one that should come first *in memory*. + So use &CONST_DOUBLE_LOW(r) as the address of an array of ints. */ +#define CONST_DOUBLE_LOW(r) XWINT (r, 2) +#define CONST_DOUBLE_HIGH(r) XWINT (r, 3) + +/* Link for chain of all CONST_DOUBLEs in use in current function. */ +#define CONST_DOUBLE_CHAIN(r) XEXP (r, 1) +/* The MEM which represents this CONST_DOUBLE's value in memory, + or const0_rtx if no MEM has been made for it yet, + or cc0_rtx if it is not on the chain. */ +#define CONST_DOUBLE_MEM(r) XEXP (r, 0) + +/* Function to return a real value (not a tree node) + from a given integer constant. */ +REAL_VALUE_TYPE real_value_from_int_cst (); + +/* Given a CONST_DOUBLE in FROM, store into TO the value it represents. */ + +#define REAL_VALUE_FROM_CONST_DOUBLE(to, from) \ +do { union real_extract u; \ + bcopy ((char *) &CONST_DOUBLE_LOW ((from)), (char *) &u, sizeof u); \ + to = u.d; } while (0) + +/* Return a CONST_DOUBLE with value R and mode M. */ + +#define CONST_DOUBLE_FROM_REAL_VALUE(r, m) immed_real_const_1 (r, m) +extern struct rtx_def *immed_real_const_1 PROTO((REAL_VALUE_TYPE, + enum machine_mode)); + + +/* Convert a floating point value `r', that can be interpreted + as a host machine float or double, to a decimal ASCII string `s' + using printf format string `fmt'. */ +#ifndef REAL_VALUE_TO_DECIMAL +#define REAL_VALUE_TO_DECIMAL(r, fmt, s) (sprintf (s, fmt, r)) +#endif + +#endif /* Not REAL_H_INCLUDED */ diff --git a/gnu/usr.bin/cc/include/recog.h b/gnu/usr.bin/cc/include/recog.h new file mode 100644 index 0000000..8fc2efb --- /dev/null +++ b/gnu/usr.bin/cc/include/recog.h @@ -0,0 +1,120 @@ +/* Declarations for interface to insn recognizer and insn-output.c. + Copyright (C) 1987 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Add prototype support. */ +#ifndef PROTO +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define PROTO(ARGS) ARGS +#else +#define PROTO(ARGS) () +#endif +#endif + +/* Recognize an insn and return its insn-code, + which is the sequence number of the DEFINE_INSN that it matches. + If the insn does not match, return -1. */ + +extern int recog_memoized PROTO((rtx)); + +/* Determine whether a proposed change to an insn or MEM will make it + invalid. Make the change if not. */ + +extern int validate_change PROTO((rtx, rtx *, rtx, int)); + +/* Apply a group of changes if valid. */ + +extern int apply_change_group PROTO((void)); + +/* Return the number of changes so far in the current group. */ + +extern int num_validated_changes PROTO((void)); + +/* Retract some changes. */ + +extern void cancel_changes PROTO((int)); + +/* Nonzero means volatile operands are recognized. */ + +extern int volatile_ok; + +/* Extract the operands from an insn that has been recognized. */ + +extern void insn_extract PROTO((rtx)); + +/* The following vectors hold the results from insn_extract. */ + +/* Indexed by N, gives value of operand N. */ +extern rtx recog_operand[]; + +/* Indexed by N, gives location where operand N was found. */ +extern rtx *recog_operand_loc[]; + +/* Indexed by N, gives location where the Nth duplicate-appearance of + an operand was found. This is something that matched MATCH_DUP. */ +extern rtx *recog_dup_loc[]; + +/* Indexed by N, gives the operand number that was duplicated in the + Nth duplicate-appearance of an operand. */ +extern char recog_dup_num[]; + +#ifndef __STDC__ +#ifndef const +#define const +#endif +#endif + +/* Access the output function for CODE. */ + +#define OUT_FCN(CODE) (*insn_outfun[(int) (CODE)]) + +/* Tables defined in insn-output.c that give information about + each insn-code value. */ + +/* These are vectors indexed by insn-code. Details in genoutput.c. */ + +extern char *const insn_template[]; + +extern char *(*const insn_outfun[]) (); + +extern const int insn_n_operands[]; + +extern const int insn_n_dups[]; + +/* Indexed by insn code number, gives # of constraint alternatives. */ + +extern const int insn_n_alternatives[]; + +/* These are two-dimensional arrays indexed first by the insn-code + and second by the operand number. Details in genoutput.c. */ + +#ifdef REGISTER_CONSTRAINTS /* Avoid undef sym in certain broken linkers. */ +extern char *const insn_operand_constraint[][MAX_RECOG_OPERANDS]; +#endif + +#ifndef REGISTER_CONSTRAINTS /* Avoid undef sym in certain broken linkers. */ +extern const char insn_operand_address_p[][MAX_RECOG_OPERANDS]; +#endif + +extern const enum machine_mode insn_operand_mode[][MAX_RECOG_OPERANDS]; + +extern const char insn_operand_strict_low[][MAX_RECOG_OPERANDS]; + +extern int (*const insn_operand_predicate[][MAX_RECOG_OPERANDS]) (); + +extern char * insn_name[]; diff --git a/gnu/usr.bin/cc/include/regs.h b/gnu/usr.bin/cc/include/regs.h new file mode 100644 index 0000000..47463bf --- /dev/null +++ b/gnu/usr.bin/cc/include/regs.h @@ -0,0 +1,168 @@ +/* Define per-register tables for data flow info and register allocation. + Copyright (C) 1987, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + +#define REG_BYTES(R) mode_size[(int) GET_MODE (R)] + +/* Get the number of consecutive hard regs required to hold the REG rtx R. + When something may be an explicit hard reg, REG_SIZE is the only + valid way to get this value. You cannot get it from the regno. */ + +#define REG_SIZE(R) \ + ((mode_size[(int) GET_MODE (R)] + UNITS_PER_WORD - 1) / UNITS_PER_WORD) + +/* Maximum register number used in this function, plus one. */ + +extern int max_regno; + +/* Maximum number of SCRATCH rtx's in each block of this function. */ + +extern int max_scratch; + +/* Indexed by n, gives number of times (REG n) is used or set. + References within loops may be counted more times. */ + +extern int *reg_n_refs; + +/* Indexed by n, gives number of times (REG n) is set. */ + +extern short *reg_n_sets; + +/* Indexed by N, gives number of insns in which register N dies. + Note that if register N is live around loops, it can die + in transitions between basic blocks, and that is not counted here. + So this is only a reliable indicator of how many regions of life there are + for registers that are contained in one basic block. */ + +extern short *reg_n_deaths; + +/* Get the number of consecutive words required to hold pseudo-reg N. */ + +#define PSEUDO_REGNO_SIZE(N) \ + ((GET_MODE_SIZE (PSEUDO_REGNO_MODE (N)) + UNITS_PER_WORD - 1) \ + / UNITS_PER_WORD) + +/* Get the number of bytes required to hold pseudo-reg N. */ + +#define PSEUDO_REGNO_BYTES(N) \ + GET_MODE_SIZE (PSEUDO_REGNO_MODE (N)) + +/* Get the machine mode of pseudo-reg N. */ + +#define PSEUDO_REGNO_MODE(N) GET_MODE (regno_reg_rtx[N]) + +/* Indexed by N, gives number of CALL_INSNS across which (REG n) is live. */ + +extern int *reg_n_calls_crossed; + +/* Total number of instructions at which (REG n) is live. + The larger this is, the less priority (REG n) gets for + allocation in a hard register (in global-alloc). + This is set in flow.c and remains valid for the rest of the compilation + of the function; it is used to control register allocation. + + local-alloc.c may alter this number to change the priority. + + Negative values are special. + -1 is used to mark a pseudo reg which has a constant or memory equivalent + and is used infrequently enough that it should not get a hard register. + -2 is used to mark a pseudo reg for a parameter, when a frame pointer + is not required. global.c makes an allocno for this but does + not try to assign a hard register to it. */ + +extern int *reg_live_length; + +/* Vector of substitutions of register numbers, + used to map pseudo regs into hardware regs. */ + +extern short *reg_renumber; + +/* Vector indexed by hardware reg + saying whether that reg is ever used. */ + +extern char regs_ever_live[FIRST_PSEUDO_REGISTER]; + +/* Vector indexed by hardware reg giving its name. */ + +extern char *reg_names[FIRST_PSEUDO_REGISTER]; + +/* For each hard register, the widest mode object that it can contain. + This will be a MODE_INT mode if the register can hold integers. Otherwise + it will be a MODE_FLOAT or a MODE_CC mode, whichever is valid for the + register. */ + +extern enum machine_mode reg_raw_mode[FIRST_PSEUDO_REGISTER]; + +/* Vector indexed by regno; gives uid of first insn using that reg. + This is computed by reg_scan for use by cse and loop. + It is sometimes adjusted for subsequent changes during loop, + but not adjusted by cse even if cse invalidates it. */ + +extern int *regno_first_uid; + +/* Vector indexed by regno; gives uid of last insn using that reg. + This is computed by reg_scan for use by cse and loop. + It is sometimes adjusted for subsequent changes during loop, + but not adjusted by cse even if cse invalidates it. + This is harmless since cse won't scan through a loop end. */ + +extern int *regno_last_uid; + +/* Similar, but includes insns that mention the reg in their notes. */ + +extern int *regno_last_note_uid; + +/* Vector indexed by regno; contains 1 for a register is considered a pointer. + Reloading, etc. will use a pointer register rather than a non-pointer + as the base register in an address, when there is a choice of two regs. */ + +extern char *regno_pointer_flag; +#define REGNO_POINTER_FLAG(REGNO) regno_pointer_flag[REGNO] + +/* List made of EXPR_LIST rtx's which gives pairs of pseudo registers + that have to go in the same hard reg. */ +extern rtx regs_may_share; + +/* Vector mapping pseudo regno into the REG rtx for that register. + This is computed by reg_scan. */ + +extern rtx *regno_reg_rtx; + +/* Flag set by local-alloc or global-alloc if they decide to allocate + something in a call-clobbered register. */ + +extern int caller_save_needed; + +/* Predicate to decide whether to give a hard reg to a pseudo which + is referenced REFS times and would need to be saved and restored + around a call CALLS times. */ + +#ifndef CALLER_SAVE_PROFITABLE +#define CALLER_SAVE_PROFITABLE(REFS, CALLS) (4 * (CALLS) < (REFS)) +#endif + +/* Allocated in local_alloc. */ + +/* A list of SCRATCH rtl allocated by local-alloc. */ +extern rtx *scratch_list; +/* The basic block in which each SCRATCH is used. */ +extern int *scratch_block; +/* The length of the arrays pointed to by scratch_block and scratch_list. */ +extern int scratch_list_length; diff --git a/gnu/usr.bin/cc/include/reload.h b/gnu/usr.bin/cc/include/reload.h new file mode 100644 index 0000000..4478b6a --- /dev/null +++ b/gnu/usr.bin/cc/include/reload.h @@ -0,0 +1,235 @@ +/* Communication between reload.c and reload1.c. + Copyright (C) 1987, 1991, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* If secondary reloads are the same for inputs and outputs, define those + macros here. */ + +#ifdef SECONDARY_RELOAD_CLASS +#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, X) \ + SECONDARY_RELOAD_CLASS (CLASS, MODE, X) +#define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, X) \ + SECONDARY_RELOAD_CLASS (CLASS, MODE, X) +#endif + +/* If either macro is defined, show that we need secondary reloads. */ +#if defined(SECONDARY_INPUT_RELOAD_CLASS) || defined(SECONDARY_OUTPUT_RELOAD_CLASS) +#define HAVE_SECONDARY_RELOADS +#endif + +/* See reload.c and reload1.c for comments on these variables. */ + +/* Maximum number of reloads we can need. */ +#define MAX_RELOADS (2 * MAX_RECOG_OPERANDS * (MAX_REGS_PER_ADDRESS + 1)) + +extern rtx reload_in[MAX_RELOADS]; +extern rtx reload_out[MAX_RELOADS]; +extern rtx reload_in_reg[MAX_RELOADS]; +extern enum reg_class reload_reg_class[MAX_RELOADS]; +extern enum machine_mode reload_inmode[MAX_RELOADS]; +extern enum machine_mode reload_outmode[MAX_RELOADS]; +extern char reload_optional[MAX_RELOADS]; +extern int reload_inc[MAX_RELOADS]; +extern int reload_opnum[MAX_RELOADS]; +extern int reload_secondary_p[MAX_RELOADS]; +extern int reload_secondary_in_reload[MAX_RELOADS]; +extern int reload_secondary_out_reload[MAX_RELOADS]; +#ifdef MAX_INSN_CODE +extern enum insn_code reload_secondary_in_icode[MAX_RELOADS]; +extern enum insn_code reload_secondary_out_icode[MAX_RELOADS]; +#endif +extern int n_reloads; + +extern rtx reload_reg_rtx[MAX_RELOADS]; + +/* Encode the usage of a reload. The following codes are supported: + + RELOAD_FOR_INPUT reload of an input operand + RELOAD_FOR_OUTPUT likewise, for output + RELOAD_FOR_INSN a reload that must not conflict with anything + used in the insn, but may conflict with + something used before or after the insn + RELOAD_FOR_INPUT_ADDRESS reload for parts of the address of an object + that is an input reload + RELOAD_FOR_OUTPUT_ADDRESS likewise, for output reload + RELOAD_FOR_OPERAND_ADDRESS reload for the address of a non-reloaded + operand; these don't conflict with + any other addresses. + RELOAD_FOR_OPADDR_ADDR reload needed for RELOAD_FOR_OPERAND_ADDRESS + reloads; usually secondary reloads + RELOAD_OTHER none of the above, usually multiple uses + RELOAD_FOR_OTHER_ADDRESS reload for part of the address of an input + that is marked RELOAD_OTHER. + + This used to be "enum reload_when_needed" but some debuggers have trouble + with an enum tag and variable of the same name. */ + +enum reload_type +{ + RELOAD_FOR_INPUT, RELOAD_FOR_OUTPUT, RELOAD_FOR_INSN, + RELOAD_FOR_INPUT_ADDRESS, RELOAD_FOR_OUTPUT_ADDRESS, + RELOAD_FOR_OPERAND_ADDRESS, RELOAD_FOR_OPADDR_ADDR, + RELOAD_OTHER, RELOAD_FOR_OTHER_ADDRESS +}; + +extern enum reload_type reload_when_needed[MAX_RELOADS]; + +extern rtx *reg_equiv_constant; +extern rtx *reg_equiv_memory_loc; +extern rtx *reg_equiv_address; +extern rtx *reg_equiv_mem; + +/* All the "earlyclobber" operands of the current insn + are recorded here. */ +extern int n_earlyclobbers; +extern rtx reload_earlyclobbers[MAX_RECOG_OPERANDS]; + +/* Save the number of operands. */ +extern int reload_n_operands; + +/* First uid used by insns created by reload in this function. + Used in find_equiv_reg. */ +extern int reload_first_uid; + +/* Nonzero if indirect addressing is supported when the innermost MEM is + of the form (MEM (SYMBOL_REF sym)). It is assumed that the level to + which these are valid is the same as spill_indirect_levels, above. */ + +extern char indirect_symref_ok; + +/* Nonzero if an address (plus (reg frame_pointer) (reg ...)) is valid. */ +extern char double_reg_address_ok; + +#ifdef MAX_INSN_CODE +/* These arrays record the insn_code of insns that may be needed to + perform input and output reloads of special objects. They provide a + place to pass a scratch register. */ +extern enum insn_code reload_in_optab[]; +extern enum insn_code reload_out_optab[]; +#endif + +/* Functions from reload.c: */ + +/* Return a memory location that will be used to copy X in mode MODE. + If we haven't already made a location for this mode in this insn, + call find_reloads_address on the location being returned. */ +extern rtx get_secondary_mem PROTO((rtx, enum machine_mode, + int, enum reload_type)); + +/* Clear any secondary memory locations we've made. */ +extern void clear_secondary_mem PROTO((void)); + +/* Transfer all replacements that used to be in reload FROM to be in + reload TO. */ +extern void transfer_replacements PROTO((int, int)); + +/* Return 1 if ADDR is a valid memory address for mode MODE, + and check that each pseudo reg has the proper kind of + hard reg. */ +extern int strict_memory_address_p PROTO((enum machine_mode, rtx)); + +/* Like rtx_equal_p except that it allows a REG and a SUBREG to match + if they are the same hard reg, and has special hacks for + autoincrement and autodecrement. */ +extern int operands_match_p PROTO((rtx, rtx)); + +/* Return the number of times character C occurs in string S. */ +extern int n_occurrences PROTO((int, char *)); + +/* Return 1 if altering OP will not modify the value of CLOBBER. */ +extern int safe_from_earlyclobber PROTO((rtx, rtx)); + +/* Search the body of INSN for values that need reloading and record them + with push_reload. REPLACE nonzero means record also where the values occur + so that subst_reloads can be used. */ +extern void find_reloads PROTO((rtx, int, int, int, short *)); + +/* Compute the sum of X and Y, making canonicalizations assumed in an + address, namely: sum constant integers, surround the sum of two + constants with a CONST, put the constant as the second operand, and + group the constant on the outermost sum. */ +extern rtx form_sum PROTO((rtx, rtx)); + +/* Substitute into the current INSN the registers into which we have reloaded + the things that need reloading. */ +extern void subst_reloads PROTO((void)); + +/* Make a copy of any replacements being done into X and move those copies + to locations in Y, a copy of X. We only look at the highest level of + the RTL. */ +extern void copy_replacements PROTO((rtx, rtx)); + +/* If LOC was scheduled to be replaced by something, return the replacement. + Otherwise, return *LOC. */ +extern rtx find_replacement PROTO((rtx *)); + +/* Return nonzero if register in range [REGNO, ENDREGNO) + appears either explicitly or implicitly in X + other than being stored into. */ +extern int refers_to_regno_for_reload_p PROTO((int, int, rtx, rtx *)); + +/* Nonzero if modifying X will affect IN. */ +extern int reg_overlap_mentioned_for_reload_p PROTO((rtx, rtx)); + +/* Return nonzero if anything in X contains a MEM. Look also for pseudo + registers. */ +extern int refers_to_mem_for_reload_p PROTO((rtx)); + +/* Check the insns before INSN to see if there is a suitable register + containing the same value as GOAL. */ +extern rtx find_equiv_reg PROTO((rtx, rtx, enum reg_class, int, short *, + int, enum machine_mode)); + +/* Return 1 if register REGNO is the subject of a clobber in insn INSN. */ +extern int regno_clobbered_p PROTO((int, rtx)); + + +/* Functions in reload1.c: */ + +/* Initialize the reload pass once per compilation. */ +extern void init_reload PROTO((void)); + +/* The reload pass itself. */ +extern int reload STDIO_PROTO((rtx, int, FILE *)); + +/* Mark the slots in regs_ever_live for the hard regs + used by pseudo-reg number REGNO. */ +extern void mark_home_live PROTO((int)); + +/* Scan X and replace any eliminable registers (such as fp) with a + replacement (such as sp), plus an offset. */ +extern rtx eliminate_regs PROTO((rtx, enum machine_mode, rtx)); + +/* Emit code to perform an input reload of IN to RELOADREG. IN is from + operand OPNUM with reload type TYPE. */ +extern rtx gen_input_reload PROTO((rtx, rtx, int, enum reload_type)); + +/* Functions in caller-save.c: */ + +/* Initialize for caller-save. */ +extern void init_caller_save PROTO((void)); + +/* Initialize save areas by showing that we haven't allocated any yet. */ +extern void init_save_areas PROTO((void)); + +/* Allocate save areas for any hard registers that might need saving. */ +extern int setup_save_areas PROTO((int *)); + +/* Find the places where hard regs are live across calls and save them. */ +extern void save_call_clobbered_regs PROTO((enum machine_mode)); diff --git a/gnu/usr.bin/cc/include/rtl.def b/gnu/usr.bin/cc/include/rtl.def new file mode 100644 index 0000000..686ad21 --- /dev/null +++ b/gnu/usr.bin/cc/include/rtl.def @@ -0,0 +1,764 @@ +/* This file contains the definitions and documentation for the + Register Transfer Expressions (rtx's) that make up the + Register Transfer Language (rtl) used in the Back End of the GNU compiler. + Copyright (C) 1987, 1988, 1992, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* Expression definitions and descriptions for all targets are in this file. + Some will not be used for some targets. + + The fields in the cpp macro call "DEF_RTL_EXPR()" + are used to create declarations in the C source of the compiler. + + The fields are: + + 1. The internal name of the rtx used in the C source. + It is a tag in the enumeration "enum rtx_code" defined in "rtl.h". + By convention these are in UPPER_CASE. + + 2. The name of the rtx in the external ASCII format read by + read_rtx(), and printed by print_rtx(). + These names are stored in rtx_name[]. + By convention these are the internal (field 1) names in lower_case. + + 3. The print format, and type of each rtx->fld[] (field) in this rtx. + These formats are stored in rtx_format[]. + The meaning of the formats is documented in front of this array in rtl.c + + 4. The class of the rtx. These are stored in rtx_class and are accessed + via the GET_RTX_CLASS macro. They are defined as follows: + + "o" an rtx code that can be used to represent an object (e.g, REG, MEM) + "<" an rtx code for a comparison (e.g, EQ, NE, LT) + "1" an rtx code for a unary arithmetic expression (e.g, NEG, NOT) + "c" an rtx code for a commutative binary operation (e.g,, PLUS, MULT) + "3" an rtx code for a non-bitfield three input operation (IF_THEN_ELSE) + "2" an rtx code for a non-commutative binary operation (e.g., MINUS, DIV) + "b" an rtx code for a bit-field operation (ZERO_EXTRACT, SIGN_EXTRACT) + "i" an rtx code for a machine insn (INSN, JUMP_INSN, CALL_INSN) + "m" an rtx code for something that matches in insns (e.g, MATCH_DUP) + "x" everything else + + */ + +/* --------------------------------------------------------------------- + Expressions (and "meta" expressions) used for structuring the + rtl representation of a program. + --------------------------------------------------------------------- */ + +/* an expression code name unknown to the reader */ +DEF_RTL_EXPR(UNKNOWN, "UnKnown", "*", 'x') + +/* (NIL) is used by rtl reader and printer to represent a null pointer. */ + +DEF_RTL_EXPR(NIL, "nil", "*", 'x') + +/* --------------------------------------------------------------------- + Expressions used in constructing lists. + --------------------------------------------------------------------- */ + +/* a linked list of expressions */ +DEF_RTL_EXPR(EXPR_LIST, "expr_list", "ee", 'x') + +/* a linked list of instructions. + The insns are represented in print by their uids. */ +DEF_RTL_EXPR(INSN_LIST, "insn_list", "ue", 'x') + +/* ---------------------------------------------------------------------- + Expression types for machine descriptions. + These do not appear in actual rtl code in the compiler. + ---------------------------------------------------------------------- */ + +/* Appears only in machine descriptions. + Means use the function named by the second arg (the string) + as a predicate; if matched, store the structure that was matched + in the operand table at index specified by the first arg (the integer). + If the second arg is the null string, the structure is just stored. + + A third string argument indicates to the register allocator restrictions + on where the operand can be allocated. + + If the target needs no restriction on any instruction this field should + be the null string. + + The string is prepended by: + '=' to indicate the operand is only written to. + '+' to indicate the operand is both read and written to. + + Each character in the string represents an allocatable class for an operand. + 'g' indicates the operand can be any valid class. + 'i' indicates the operand can be immediate (in the instruction) data. + 'r' indicates the operand can be in a register. + 'm' indicates the operand can be in memory. + 'o' a subset of the 'm' class. Those memory addressing modes that + can be offset at compile time (have a constant added to them). + + Other characters indicate target dependent operand classes and + are described in each target's machine description. + + For instructions with more than one operand, sets of classes can be + separated by a comma to indicate the appropriate multi-operand constraints. + There must be a 1 to 1 correspondence between these sets of classes in + all operands for an instruction. + */ +DEF_RTL_EXPR(MATCH_OPERAND, "match_operand", "iss", 'm') + +/* Appears only in machine descriptions. + Means match a SCRATCH or a register. When used to generate rtl, a + SCRATCH is generated. As for MATCH_OPERAND, the mode specifies + the desired mode and the first argument is the operand number. + The second argument is the constraint. */ +DEF_RTL_EXPR(MATCH_SCRATCH, "match_scratch", "is", 'm') + +/* Appears only in machine descriptions. + Means match only something equal to what is stored in the operand table + at the index specified by the argument. */ +DEF_RTL_EXPR(MATCH_DUP, "match_dup", "i", 'm') + +/* Appears only in machine descriptions. + Means apply a predicate, AND match recursively the operands of the rtx. + Operand 0 is the operand-number, as in match_operand. + Operand 1 is a predicate to apply (as a string, a function name). + Operand 2 is a vector of expressions, each of which must match + one subexpression of the rtx this construct is matching. */ +DEF_RTL_EXPR(MATCH_OPERATOR, "match_operator", "isE", 'm') + +/* Appears only in machine descriptions. + Means to match a PARALLEL of arbitrary length. The predicate is applied + to the PARALLEL and the initial expressions in the PARALLEL are matched. + Operand 0 is the operand-number, as in match_operand. + Operand 1 is a predicate to apply to the PARALLEL. + Operand 2 is a vector of expressions, each of which must match the + corresponding element in the PARALLEL. */ +DEF_RTL_EXPR(MATCH_PARALLEL, "match_parallel", "isE", 'm') + +/* Appears only in machine descriptions. + Means match only something equal to what is stored in the operand table + at the index specified by the argument. For MATCH_OPERATOR. */ +DEF_RTL_EXPR(MATCH_OP_DUP, "match_op_dup", "iE", 'm') + +/* Appears only in machine descriptions. + Means match only something equal to what is stored in the operand table + at the index specified by the argument. For MATCH_PARALLEL. */ +DEF_RTL_EXPR(MATCH_PAR_DUP, "match_par_dup", "iE", 'm') + +/* Appears only in machine descriptions. + Defines the pattern for one kind of instruction. + Operand: + 0: names this instruction. + If the name is the null string, the instruction is in the + machine description just to be recognized, and will never be emitted by + the tree to rtl expander. + 1: is the pattern. + 2: is a string which is a C expression + giving an additional condition for recognizing this pattern. + A null string means no extra condition. + 3: is the action to execute if this pattern is matched. + If this assembler code template starts with a * then it is a fragment of + C code to run to decide on a template to use. Otherwise, it is the + template to use. + 4: optionally, a vector of attributes for this insn. + */ +DEF_RTL_EXPR(DEFINE_INSN, "define_insn", "sEssV", 'x') + +/* Definition of a peephole optimization. + 1st operand: vector of insn patterns to match + 2nd operand: C expression that must be true + 3rd operand: template or C code to produce assembler output. + 4: optionally, a vector of attributes for this insn. + */ +DEF_RTL_EXPR(DEFINE_PEEPHOLE, "define_peephole", "EssV", 'x') + +/* Definition of a split operation. + 1st operand: insn pattern to match + 2nd operand: C expression that must be true + 3rd operand: vector of insn patterns to place into a SEQUENCE + 4th operand: optionally, some C code to execute before generating the + insns. This might, for example, create some RTX's and store them in + elements of `recog_operand' for use by the vector of insn-patterns. + (`operands' is an alias here for `recog_operand'). */ +DEF_RTL_EXPR(DEFINE_SPLIT, "define_split", "EsES", 'x') + +/* Definition of a combiner pattern. + Operands not defined yet. */ +DEF_RTL_EXPR(DEFINE_COMBINE, "define_combine", "Ess", 'x') + +/* Define how to generate multiple insns for a standard insn name. + 1st operand: the insn name. + 2nd operand: vector of insn-patterns. + Use match_operand to substitute an element of `recog_operand'. + 3rd operand: C expression that must be true for this to be available. + This may not test any operands. + 4th operand: Extra C code to execute before generating the insns. + This might, for example, create some RTX's and store them in + elements of `recog_operand' for use by the vector of insn-patterns. + (`operands' is an alias here for `recog_operand'). */ +DEF_RTL_EXPR(DEFINE_EXPAND, "define_expand", "sEss", 'x') + +/* Define a requirement for delay slots. + 1st operand: Condition involving insn attributes that, if true, + indicates that the insn requires the number of delay slots + shown. + 2nd operand: Vector whose length is the three times the number of delay + slots required. + Each entry gives three conditions, each involving attributes. + The first must be true for an insn to occupy that delay slot + location. The second is true for all insns that can be + annulled if the branch is true and the third is true for all + insns that can be annulled if the branch is false. + + Multiple DEFINE_DELAYs may be present. They indicate differing + requirements for delay slots. */ +DEF_RTL_EXPR(DEFINE_DELAY, "define_delay", "eE", 'x') + +/* Define a set of insns that requires a function unit. This means that + these insns produce their result after a delay and that there may be + restrictions on the number of insns of this type that can be scheduled + simultaneously. + + More than one DEFINE_FUNCTION_UNIT can be specified for a function unit. + Each gives a set of operations and associated delays. The first three + operands must be the same for each operation for the same function unit. + + All delays are specified in cycles. + + 1st operand: Name of function unit (mostly for documentation) + 2nd operand: Number of identical function units in CPU + 3rd operand: Total number of simultaneous insns that can execute on this + function unit; 0 if unlimited. + 4th operand: Condition involving insn attribute, that, if true, specifies + those insns that this expression applies to. + 5th operand: Constant delay after which insn result will be + available. + 6th operand: Delay until next insn can be scheduled on the function unit + executing this operation. The meaning depends on whether or + not the next operand is supplied. + 7th operand: If this operand is not specified, the 6th operand gives the + number of cycles after the instruction matching the 4th + operand begins using the function unit until a subsequent + insn can begin. A value of zero should be used for a + unit with no issue constraints. If only one operation can + be executed a time and the unit is busy for the entire time, + the 3rd operand should be specified as 1, the 6th operand + sould be specified as 0, and the 7th operand should not + be specified. + + If this operand is specified, it is a list of attribute + expressions. If an insn for which any of these expressions + is true is currently executing on the function unit, the + issue delay will be given by the 6th operand. Otherwise, + the insn can be immediately scheduled (subject to the limit + on the number of simultaneous operations executing on the + unit.) */ +DEF_RTL_EXPR(DEFINE_FUNCTION_UNIT, "define_function_unit", "siieiiV", 'x') + +/* Define attribute computation for `asm' instructions. */ +DEF_RTL_EXPR(DEFINE_ASM_ATTRIBUTES, "define_asm_attributes", "V", 'x' ) + +/* SEQUENCE appears in the result of a `gen_...' function + for a DEFINE_EXPAND that wants to make several insns. + Its elements are the bodies of the insns that should be made. + `emit_insn' takes the SEQUENCE apart and makes separate insns. */ +DEF_RTL_EXPR(SEQUENCE, "sequence", "E", 'x') + +/* Refers to the address of its argument. + This appears only in machine descriptions, indicating that + any expression that would be acceptable as the operand of MEM + should be matched. */ +DEF_RTL_EXPR(ADDRESS, "address", "e", 'm') + +/* ---------------------------------------------------------------------- + Expressions used for insn attributes. These also do not appear in + actual rtl code in the compiler. + ---------------------------------------------------------------------- */ + +/* Definition of an insn attribute. + 1st operand: name of the attribute + 2nd operand: comma-separated list of possible attribute values + 3rd operand: expression for the default value of the attribute. */ +DEF_RTL_EXPR(DEFINE_ATTR, "define_attr", "sse", 'x') + +/* Marker for the name of an attribute. */ +DEF_RTL_EXPR(ATTR, "attr", "s", 'x') + +/* For use in the last (optional) operand of DEFINE_INSN or DEFINE_PEEPHOLE and + in DEFINE_ASM_INSN to specify an attribute to assign to insns matching that + pattern. + + (set_attr "name" "value") is equivalent to + (set (attr "name") (const_string "value")) */ +DEF_RTL_EXPR(SET_ATTR, "set_attr", "ss", 'x') + +/* In the last operand of DEFINE_INSN and DEFINE_PEEPHOLE, this can be used to + specify that attribute values are to be assigned according to the + alternative matched. + + The following three expressions are equivalent: + + (set (attr "att") (cond [(eq_attrq "alternative" "1") (const_string "a1") + (eq_attrq "alternative" "2") (const_string "a2")] + (const_string "a3"))) + (set_attr_alternative "att" [(const_string "a1") (const_string "a2") + (const_string "a3")]) + (set_attr "att" "a1,a2,a3") + */ +DEF_RTL_EXPR(SET_ATTR_ALTERNATIVE, "set_attr_alternative", "sE", 'x') + +/* A conditional expression true if the value of the specified attribute of + the current insn equals the specified value. The first operand is the + attribute name and the second is the comparison value. */ +DEF_RTL_EXPR(EQ_ATTR, "eq_attr", "ss", 'x') + +/* A conditional expression which is true if the specified flag is + true for the insn being scheduled in reorg. + + genattr.c defines the following flags which can be tested by + (attr_flag "foo") expressions in eligible_for_delay. + + forward, backward, very_likely, likely, very_unlikely, and unlikely. */ + +DEF_RTL_EXPR (ATTR_FLAG, "attr_flag", "s", 'x') + +/* ---------------------------------------------------------------------- + Expression types used for things in the instruction chain. + + All formats must start with "iuu" to handle the chain. + Each insn expression holds an rtl instruction and its semantics + during back-end processing. + See macros's in "rtl.h" for the meaning of each rtx->fld[]. + + ---------------------------------------------------------------------- */ + +/* An instruction that cannot jump. */ +DEF_RTL_EXPR(INSN, "insn", "iuueiee", 'i') + +/* An instruction that can possibly jump. + Fields ( rtx->fld[] ) have exact same meaning as INSN's. */ +DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "iuueiee0", 'i') + +/* An instruction that can possibly call a subroutine + but which will not change which instruction comes next + in the current function. + Field ( rtx->fld[7] ) is CALL_INSN_FUNCTION_USAGE. + All other fields ( rtx->fld[] ) have exact same meaning as INSN's. */ +DEF_RTL_EXPR(CALL_INSN, "call_insn", "iuueieee", 'i') + +/* A marker that indicates that control will not flow through. */ +DEF_RTL_EXPR(BARRIER, "barrier", "iuu", 'x') + +/* Holds a label that is followed by instructions. + Operand: + 3: is a number that is unique in the entire compilation. + 4: is the user-given name of the label, if any. + 5: is used in jump.c for the use-count of the label. + and in flow.c to point to the chain of label_ref's to this label. */ +DEF_RTL_EXPR(CODE_LABEL, "code_label", "iuuis0", 'x') + +/* Say where in the code a source line starts, for symbol table's sake. + Contains a filename and a line number. Line numbers <= 0 are special: + 0 is used in a dummy placed at the front of every function + just so there will never be a need to delete the first insn; + -1 indicates a dummy; insns to be deleted by flow analysis and combining + are really changed to NOTEs with a number of -1. + -2 means beginning of a name binding contour; output N_LBRAC. + -3 means end of a contour; output N_RBRAC. */ +DEF_RTL_EXPR(NOTE, "note", "iuusn", 'x') + +/* INLINE_HEADER is use by inline function machinery. The information + it contains helps to build the mapping function between the rtx's of + the function to be inlined and the current function being expanded. */ + +DEF_RTL_EXPR(INLINE_HEADER, "inline_header", "iuuuiiiiiieiiEe", 'x') + +/* ---------------------------------------------------------------------- + Top level constituents of INSN, JUMP_INSN and CALL_INSN. + ---------------------------------------------------------------------- */ + +/* Several operations to be done in parallel. */ +DEF_RTL_EXPR(PARALLEL, "parallel", "E", 'x') + +/* A string that is passed through to the assembler as input. + One can obviously pass comments through by using the + assembler comment syntax. + These occur in an insn all by themselves as the PATTERN. + They also appear inside an ASM_OPERANDS + as a convenient way to hold a string. */ +DEF_RTL_EXPR(ASM_INPUT, "asm_input", "s", 'x') + +/* An assembler instruction with operands. + 1st operand is the instruction template. + 2nd operand is the constraint for the output. + 3rd operand is the number of the output this expression refers to. + When an insn stores more than one value, a separate ASM_OPERANDS + is made for each output; this integer distinguishes them. + 4th is a vector of values of input operands. + 5th is a vector of modes and constraints for the input operands. + Each element is an ASM_INPUT containing a constraint string + and whose mode indicates the mode of the input operand. + 6th is the name of the containing source file. + 7th is the source line number. */ +DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEsi", 'x') + +/* A machine-specific operation. + 1st operand is a vector of operands being used by the operation so that + any needed reloads can be done. + 2nd operand is a unique value saying which of a number of machine-specific + operations is to be performed. + (Note that the vector must be the first operand because of the way that + genrecog.c record positions within an insn.) + This can occur all by itself in a PATTERN, as a component of a PARALLEL, + or inside an expression. */ +DEF_RTL_EXPR(UNSPEC, "unspec", "Ei", 'x') + +/* Similar, but a volatile operation and one which may trap. */ +DEF_RTL_EXPR(UNSPEC_VOLATILE, "unspec_volatile", "Ei", 'x') + +/* Vector of addresses, stored as full words. */ +/* Each element is a LABEL_REF to a CODE_LABEL whose address we want. */ +DEF_RTL_EXPR(ADDR_VEC, "addr_vec", "E", 'x') + +/* Vector of address differences X0 - BASE, X1 - BASE, ... + First operand is BASE; the vector contains the X's. + The machine mode of this rtx says how much space to leave + for each difference. */ +DEF_RTL_EXPR(ADDR_DIFF_VEC, "addr_diff_vec", "eE", 'x') + +/* ---------------------------------------------------------------------- + At the top level of an instruction (perhaps under PARALLEL). + ---------------------------------------------------------------------- */ + +/* Assignment. + Operand 1 is the location (REG, MEM, PC, CC0 or whatever) assigned to. + Operand 2 is the value stored there. + ALL assignment must use SET. + Instructions that do multiple assignments must use multiple SET, + under PARALLEL. */ +DEF_RTL_EXPR(SET, "set", "ee", 'x') + +/* Indicate something is used in a way that we don't want to explain. + For example, subroutine calls will use the register + in which the static chain is passed. */ +DEF_RTL_EXPR(USE, "use", "e", 'x') + +/* Indicate something is clobbered in a way that we don't want to explain. + For example, subroutine calls will clobber some physical registers + (the ones that are by convention not saved). */ +DEF_RTL_EXPR(CLOBBER, "clobber", "e", 'x') + +/* Call a subroutine. + Operand 1 is the address to call. + Operand 2 is the number of arguments. */ + +DEF_RTL_EXPR(CALL, "call", "ee", 'x') + +/* Return from a subroutine. */ + +DEF_RTL_EXPR(RETURN, "return", "", 'x') + +/* Conditional trap. + Operand 1 is the condition. + Operand 2 is the trap code. + For an unconditional trap, make the condition (const_int 1). */ +DEF_RTL_EXPR(TRAP_IF, "trap_if", "ei", 'x') + +/* ---------------------------------------------------------------------- + Primitive values for use in expressions. + ---------------------------------------------------------------------- */ + +/* numeric integer constant */ +DEF_RTL_EXPR(CONST_INT, "const_int", "w", 'o') + +/* numeric double constant. + Operand 0 is the MEM that stores this constant in memory, + or various other things (see comments at immed_double_const in varasm.c). + Operand 1 is a chain of all CONST_DOUBLEs in use in the current function. + Remaining operands hold the actual value. + The number of operands may be more than 2 if cross-compiling; + see init_rtl. */ +DEF_RTL_EXPR(CONST_DOUBLE, "const_double", "e0ww", 'o') + +/* String constant. Used only for attributes right now. */ +DEF_RTL_EXPR(CONST_STRING, "const_string", "s", 'o') + +/* This is used to encapsulate an expression whose value is constant + (such as the sum of a SYMBOL_REF and a CONST_INT) so that it will be + recognized as a constant operand rather than by arithmetic instructions. */ + +DEF_RTL_EXPR(CONST, "const", "e", 'o') + +/* program counter. Ordinary jumps are represented + by a SET whose first operand is (PC). */ +DEF_RTL_EXPR(PC, "pc", "", 'o') + +/* A register. The "operand" is the register number, accessed + with the REGNO macro. If this number is less than FIRST_PSEUDO_REGISTER + than a hardware register is being referred to. */ +DEF_RTL_EXPR(REG, "reg", "i", 'o') + +/* A scratch register. This represents a register used only within a + single insn. It will be turned into a REG during register allocation + or reload unless the constraint indicates that the register won't be + needed, in which case it can remain a SCRATCH. This code is + marked as having one operand so it can be turned into a REG. */ +DEF_RTL_EXPR(SCRATCH, "scratch", "0", 'o') + +/* One word of a multi-word value. + The first operand is the complete value; the second says which word. + The WORDS_BIG_ENDIAN flag controls whether word number 0 + (as numbered in a SUBREG) is the most or least significant word. + + This is also used to refer to a value in a different machine mode. + For example, it can be used to refer to a SImode value as if it were + Qimode, or vice versa. Then the word number is always 0. */ +DEF_RTL_EXPR(SUBREG, "subreg", "ei", 'x') + +/* This one-argument rtx is used for move instructions + that are guaranteed to alter only the low part of a destination. + Thus, (SET (SUBREG:HI (REG...)) (MEM:HI ...)) + has an unspecified effect on the high part of REG, + but (SET (STRICT_LOW_PART (SUBREG:HI (REG...))) (MEM:HI ...)) + is guaranteed to alter only the bits of REG that are in HImode. + + The actual instruction used is probably the same in both cases, + but the register constraints may be tighter when STRICT_LOW_PART + is in use. */ + +DEF_RTL_EXPR(STRICT_LOW_PART, "strict_low_part", "e", 'x') + +/* (CONCAT a b) represents the virtual concatenation of a and b + to make a value that has as many bits as a and b put together. + This is used for complex values. Normally it appears only + in DECL_RTLs and during RTL generation, but not in the insn chain. */ +DEF_RTL_EXPR(CONCAT, "concat", "ee", 'o') + +/* A memory location; operand is the address. + Can be nested inside a VOLATILE. */ +DEF_RTL_EXPR(MEM, "mem", "e", 'o') + +/* Reference to an assembler label in the code for this function. + The operand is a CODE_LABEL found in the insn chain. + The unprinted fields 1 and 2 are used in flow.c for the + LABEL_NEXTREF and CONTAINING_INSN. */ +DEF_RTL_EXPR(LABEL_REF, "label_ref", "u00", 'o') + +/* Reference to a named label: the string that is the first operand, + with `_' added implicitly in front. + Exception: if the first character explicitly given is `*', + to give it to the assembler, remove the `*' and do not add `_'. */ +DEF_RTL_EXPR(SYMBOL_REF, "symbol_ref", "s", 'o') + +/* The condition code register is represented, in our imagination, + as a register holding a value that can be compared to zero. + In fact, the machine has already compared them and recorded the + results; but instructions that look at the condition code + pretend to be looking at the entire value and comparing it. */ +DEF_RTL_EXPR(CC0, "cc0", "", 'o') + +/* ===================================================================== + A QUEUED expression really points to a member of the queue of instructions + to be output later for postincrement/postdecrement. + QUEUED expressions never become part of instructions. + When a QUEUED expression would be put into an instruction, + instead either the incremented variable or a copy of its previous + value is used. + + Operands are: + 0. the variable to be incremented (a REG rtx). + 1. the incrementing instruction, or 0 if it hasn't been output yet. + 2. A REG rtx for a copy of the old value of the variable, or 0 if none yet. + 3. the body to use for the incrementing instruction + 4. the next QUEUED expression in the queue. + ====================================================================== */ + +DEF_RTL_EXPR(QUEUED, "queued", "eeeee", 'x') + +/* ---------------------------------------------------------------------- + Expressions for operators in an rtl pattern + ---------------------------------------------------------------------- */ + +/* if_then_else. This is used in representing ordinary + conditional jump instructions. + Operand: + 0: condition + 1: then expr + 2: else expr */ +DEF_RTL_EXPR(IF_THEN_ELSE, "if_then_else", "eee", '3') + +/* General conditional. The first operand is a vector composed of pairs of + expressions. The first element of each pair is evaluated, in turn. + The value of the conditional is the second expression of the first pair + whose first expression evaluates non-zero. If none of the expressions is + true, the second operand will be used as the value of the conditional. + + This should be replaced with use of IF_THEN_ELSE. */ +DEF_RTL_EXPR(COND, "cond", "Ee", 'x') + +/* Comparison, produces a condition code result. */ +DEF_RTL_EXPR(COMPARE, "compare", "ee", '2') + +/* plus */ +DEF_RTL_EXPR(PLUS, "plus", "ee", 'c') + +/* Operand 0 minus operand 1. */ +DEF_RTL_EXPR(MINUS, "minus", "ee", '2') + +/* Minus operand 0. */ +DEF_RTL_EXPR(NEG, "neg", "e", '1') + +DEF_RTL_EXPR(MULT, "mult", "ee", 'c') + +/* Operand 0 divided by operand 1. */ +DEF_RTL_EXPR(DIV, "div", "ee", '2') +/* Remainder of operand 0 divided by operand 1. */ +DEF_RTL_EXPR(MOD, "mod", "ee", '2') + +/* Unsigned divide and remainder. */ +DEF_RTL_EXPR(UDIV, "udiv", "ee", '2') +DEF_RTL_EXPR(UMOD, "umod", "ee", '2') + +/* Bitwise operations. */ +DEF_RTL_EXPR(AND, "and", "ee", 'c') + +DEF_RTL_EXPR(IOR, "ior", "ee", 'c') + +DEF_RTL_EXPR(XOR, "xor", "ee", 'c') + +DEF_RTL_EXPR(NOT, "not", "e", '1') + +/* Operand: + 0: value to be shifted. + 1: number of bits. */ +DEF_RTL_EXPR(ASHIFT, "ashift", "ee", '2') +DEF_RTL_EXPR(ROTATE, "rotate", "ee", '2') + +/* Right shift operations, for machines where these are not the same + as left shifting with a negative argument. */ + +DEF_RTL_EXPR(ASHIFTRT, "ashiftrt", "ee", '2') +DEF_RTL_EXPR(LSHIFTRT, "lshiftrt", "ee", '2') +DEF_RTL_EXPR(ROTATERT, "rotatert", "ee", '2') + +/* Minimum and maximum values of two operands. We need both signed and + unsigned forms. (We cannot use MIN for SMIN because it conflicts + with a macro of the same name.) */ + +DEF_RTL_EXPR(SMIN, "smin", "ee", 'c') +DEF_RTL_EXPR(SMAX, "smax", "ee", 'c') +DEF_RTL_EXPR(UMIN, "umin", "ee", 'c') +DEF_RTL_EXPR(UMAX, "umax", "ee", 'c') + +/* These unary operations are used to represent incrementation + and decrementation as they occur in memory addresses. + The amount of increment or decrement are not represented + because they can be understood from the machine-mode of the + containing MEM. These operations exist in only two cases: + 1. pushes onto the stack. + 2. created automatically by the life_analysis pass in flow.c. */ +DEF_RTL_EXPR(PRE_DEC, "pre_dec", "e", 'x') +DEF_RTL_EXPR(PRE_INC, "pre_inc", "e", 'x') +DEF_RTL_EXPR(POST_DEC, "post_dec", "e", 'x') +DEF_RTL_EXPR(POST_INC, "post_inc", "e", 'x') + +/* Comparison operations. The ordered comparisons exist in two + flavors, signed and unsigned. */ +DEF_RTL_EXPR(NE, "ne", "ee", '<') +DEF_RTL_EXPR(EQ, "eq", "ee", '<') +DEF_RTL_EXPR(GE, "ge", "ee", '<') +DEF_RTL_EXPR(GT, "gt", "ee", '<') +DEF_RTL_EXPR(LE, "le", "ee", '<') +DEF_RTL_EXPR(LT, "lt", "ee", '<') +DEF_RTL_EXPR(GEU, "geu", "ee", '<') +DEF_RTL_EXPR(GTU, "gtu", "ee", '<') +DEF_RTL_EXPR(LEU, "leu", "ee", '<') +DEF_RTL_EXPR(LTU, "ltu", "ee", '<') + +/* Represents the result of sign-extending the sole operand. + The machine modes of the operand and of the SIGN_EXTEND expression + determine how much sign-extension is going on. */ +DEF_RTL_EXPR(SIGN_EXTEND, "sign_extend", "e", '1') + +/* Similar for zero-extension (such as unsigned short to int). */ +DEF_RTL_EXPR(ZERO_EXTEND, "zero_extend", "e", '1') + +/* Similar but here the operand has a wider mode. */ +DEF_RTL_EXPR(TRUNCATE, "truncate", "e", '1') + +/* Similar for extending floating-point values (such as SFmode to DFmode). */ +DEF_RTL_EXPR(FLOAT_EXTEND, "float_extend", "e", '1') +DEF_RTL_EXPR(FLOAT_TRUNCATE, "float_truncate", "e", '1') + +/* Conversion of fixed point operand to floating point value. */ +DEF_RTL_EXPR(FLOAT, "float", "e", '1') + +/* With fixed-point machine mode: + Conversion of floating point operand to fixed point value. + Value is defined only when the operand's value is an integer. + With floating-point machine mode (and operand with same mode): + Operand is rounded toward zero to produce an integer value + represented in floating point. */ +DEF_RTL_EXPR(FIX, "fix", "e", '1') + +/* Conversion of unsigned fixed point operand to floating point value. */ +DEF_RTL_EXPR(UNSIGNED_FLOAT, "unsigned_float", "e", '1') + +/* With fixed-point machine mode: + Conversion of floating point operand to *unsigned* fixed point value. + Value is defined only when the operand's value is an integer. */ +DEF_RTL_EXPR(UNSIGNED_FIX, "unsigned_fix", "e", '1') + +/* Absolute value */ +DEF_RTL_EXPR(ABS, "abs", "e", '1') + +/* Square root */ +DEF_RTL_EXPR(SQRT, "sqrt", "e", '1') + +/* Find first bit that is set. + Value is 1 + number of trailing zeros in the arg., + or 0 if arg is 0. */ +DEF_RTL_EXPR(FFS, "ffs", "e", '1') + +/* Reference to a signed bit-field of specified size and position. + Operand 0 is the memory unit (usually SImode or QImode) which + contains the field's first bit. Operand 1 is the width, in bits. + Operand 2 is the number of bits in the memory unit before the + first bit of this field. + If BITS_BIG_ENDIAN is defined, the first bit is the msb and + operand 2 counts from the msb of the memory unit. + Otherwise, the first bit is the lsb and operand 2 counts from + the lsb of the memory unit. */ +DEF_RTL_EXPR(SIGN_EXTRACT, "sign_extract", "eee", 'b') + +/* Similar for unsigned bit-field. */ +DEF_RTL_EXPR(ZERO_EXTRACT, "zero_extract", "eee", 'b') + +/* For RISC machines. These save memory when splitting insns. */ + +/* HIGH are the high-order bits of a constant expression. */ +DEF_RTL_EXPR(HIGH, "high", "e", 'o') + +/* LO_SUM is the sum of a register and the low-order bits + of a constant expression. */ +DEF_RTL_EXPR(LO_SUM, "lo_sum", "ee", 'o') + +/* +Local variables: +mode:c +version-control: t +End: +*/ diff --git a/gnu/usr.bin/cc/include/rtl.h b/gnu/usr.bin/cc/include/rtl.h new file mode 100644 index 0000000..b0eb1c52 --- /dev/null +++ b/gnu/usr.bin/cc/include/rtl.h @@ -0,0 +1,957 @@ +/* Register Transfer Language (RTL) definitions for GNU C-Compiler + Copyright (C) 1987, 1991, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +#include "machmode.h" + +#undef FFS /* Some systems predefine this symbol; don't let it interfere. */ +#undef FLOAT /* Likewise. */ +#undef ABS /* Likewise. */ +#undef PC /* Likewise. */ + +#ifndef TREE_CODE +union tree_node; +#endif + +/* Register Transfer Language EXPRESSIONS CODES */ + +#define RTX_CODE enum rtx_code +enum rtx_code { + +#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) ENUM , +#include "rtl.def" /* rtl expressions are documented here */ +#undef DEF_RTL_EXPR + + LAST_AND_UNUSED_RTX_CODE}; /* A convenient way to get a value for + NUM_RTX_CODE. + Assumes default enum value assignment. */ + +#define NUM_RTX_CODE ((int)LAST_AND_UNUSED_RTX_CODE) + /* The cast here, saves many elsewhere. */ + +extern int rtx_length[]; +#define GET_RTX_LENGTH(CODE) (rtx_length[(int)(CODE)]) + +extern char *rtx_name[]; +#define GET_RTX_NAME(CODE) (rtx_name[(int)(CODE)]) + +extern char *rtx_format[]; +#define GET_RTX_FORMAT(CODE) (rtx_format[(int)(CODE)]) + +extern char rtx_class[]; +#define GET_RTX_CLASS(CODE) (rtx_class[(int)(CODE)]) + +/* Common union for an element of an rtx. */ + +typedef union rtunion_def +{ + HOST_WIDE_INT rtwint; + int rtint; + char *rtstr; + struct rtx_def *rtx; + struct rtvec_def *rtvec; + enum machine_mode rttype; +} rtunion; + +/* RTL expression ("rtx"). */ + +typedef struct rtx_def +{ +#ifdef ONLY_INT_FIELDS +#ifdef CODE_FIELD_BUG + unsigned int code : 16; +#else + unsigned short code; +#endif +#else + /* The kind of expression this is. */ + enum rtx_code code : 16; +#endif + /* The kind of value the expression has. */ +#ifdef ONLY_INT_FIELDS + int mode : 8; +#else + enum machine_mode mode : 8; +#endif + /* 1 in an INSN if it can alter flow of control + within this function. Not yet used! */ + unsigned int jump : 1; + /* 1 in an INSN if it can call another function. Not yet used! */ + unsigned int call : 1; + /* 1 in a MEM or REG if value of this expression will never change + during the current function, even though it is not + manifestly constant. + 1 in a SUBREG if it is from a promoted variable that is unsigned. + 1 in a SYMBOL_REF if it addresses something in the per-function + constants pool. + 1 in a CALL_INSN if it is a const call. + 1 in a JUMP_INSN if it is a branch that should be annulled. Valid from + reorg until end of compilation; cleared before used. */ + unsigned int unchanging : 1; + /* 1 in a MEM expression if contents of memory are volatile. + 1 in an INSN, CALL_INSN, JUMP_INSN, CODE_LABEL or BARRIER + if it is deleted. + 1 in a REG expression if corresponds to a variable declared by the user. + 0 for an internally generated temporary. + In a SYMBOL_REF, this flag is used for machine-specific purposes. + In a LABEL_REF or in a REG_LABEL note, this is LABEL_REF_NONLOCAL_P. */ + unsigned int volatil : 1; + /* 1 in a MEM referring to a field of a structure (not a union!). + 0 if the MEM was a variable or the result of a * operator in C; + 1 if it was the result of a . or -> operator (on a struct) in C. + 1 in a REG if the register is used only in exit code a loop. + 1 in a SUBREG expression if was generated from a variable with a + promoted mode. + 1 in a CODE_LABEL if the label is used for nonlocal gotos + and must not be deleted even if its count is zero. + 1 in a LABEL_REF if this is a reference to a label outside the + current loop. + 1 in an INSN, JUMP_INSN, or CALL_INSN if this insn must be scheduled + together with the preceding insn. Valid only within sched. + 1 in an INSN, JUMP_INSN, or CALL_INSN if insn is in a delay slot and + from the target of a branch. Valid from reorg until end of compilation; + cleared before used. */ + unsigned int in_struct : 1; + /* 1 if this rtx is used. This is used for copying shared structure. + See `unshare_all_rtl'. + In a REG, this is not needed for that purpose, and used instead + in `leaf_renumber_regs_insn'. + In a SYMBOL_REF, means that emit_library_call + has used it as the function. */ + unsigned int used : 1; + /* Nonzero if this rtx came from procedure integration. + In a REG, nonzero means this reg refers to the return value + of the current function. */ + unsigned integrated : 1; + /* The first element of the operands of this rtx. + The number of operands and their types are controlled + by the `code' field, according to rtl.def. */ + rtunion fld[1]; +} *rtx; + + +/* Add prototype support. */ +#ifndef PROTO +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define PROTO(ARGS) ARGS +#else +#define PROTO(ARGS) () +#endif +#endif + +#ifndef VPROTO +#ifdef __STDC__ +#define PVPROTO(ARGS) ARGS +#define VPROTO(ARGS) ARGS +#define VA_START(va_list,var) va_start(va_list,var) +#else +#define PVPROTO(ARGS) () +#define VPROTO(ARGS) (va_alist) va_dcl +#define VA_START(va_list,var) va_start(va_list) +#endif +#endif + +#ifndef STDIO_PROTO +#ifdef BUFSIZ +#define STDIO_PROTO(ARGS) PROTO(ARGS) +#else +#define STDIO_PROTO(ARGS) () +#endif +#endif + +#define NULL_RTX (rtx) 0 + +/* Define a generic NULL if one hasn't already been defined. */ + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef GENERIC_PTR +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define GENERIC_PTR void * +#else +#define GENERIC_PTR char * +#endif +#endif + +#ifndef NULL_PTR +#define NULL_PTR ((GENERIC_PTR)0) +#endif + +/* Define macros to access the `code' field of the rtx. */ + +#ifdef SHORT_ENUM_BUG +#define GET_CODE(RTX) ((enum rtx_code) ((RTX)->code)) +#define PUT_CODE(RTX, CODE) ((RTX)->code = ((short) (CODE))) +#else +#define GET_CODE(RTX) ((RTX)->code) +#define PUT_CODE(RTX, CODE) ((RTX)->code = (CODE)) +#endif + +#define GET_MODE(RTX) ((RTX)->mode) +#define PUT_MODE(RTX, MODE) ((RTX)->mode = (MODE)) + +#define RTX_INTEGRATED_P(RTX) ((RTX)->integrated) +#define RTX_UNCHANGING_P(RTX) ((RTX)->unchanging) + +/* RTL vector. These appear inside RTX's when there is a need + for a variable number of things. The principle use is inside + PARALLEL expressions. */ + +typedef struct rtvec_def{ + unsigned num_elem; /* number of elements */ + rtunion elem[1]; +} *rtvec; + +#define NULL_RTVEC (rtvec) 0 + +#define GET_NUM_ELEM(RTVEC) ((RTVEC)->num_elem) +#define PUT_NUM_ELEM(RTVEC, NUM) ((RTVEC)->num_elem = (unsigned) NUM) + +#define RTVEC_ELT(RTVEC, I) ((RTVEC)->elem[(I)].rtx) + +/* 1 if X is a REG. */ + +#define REG_P(X) (GET_CODE (X) == REG) + +/* 1 if X is a constant value that is an integer. */ + +#define CONSTANT_P(X) \ + (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \ + || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST_DOUBLE \ + || GET_CODE (X) == CONST || GET_CODE (X) == HIGH) + +/* General accessor macros for accessing the fields of an rtx. */ + +#define XEXP(RTX, N) ((RTX)->fld[N].rtx) +#define XINT(RTX, N) ((RTX)->fld[N].rtint) +#define XWINT(RTX, N) ((RTX)->fld[N].rtwint) +#define XSTR(RTX, N) ((RTX)->fld[N].rtstr) +#define XVEC(RTX, N) ((RTX)->fld[N].rtvec) +#define XVECLEN(RTX, N) ((RTX)->fld[N].rtvec->num_elem) +#define XVECEXP(RTX,N,M)((RTX)->fld[N].rtvec->elem[M].rtx) + +/* ACCESS MACROS for particular fields of insns. */ + +/* Holds a unique number for each insn. + These are not necessarily sequentially increasing. */ +#define INSN_UID(INSN) ((INSN)->fld[0].rtint) + +/* Chain insns together in sequence. */ +#define PREV_INSN(INSN) ((INSN)->fld[1].rtx) +#define NEXT_INSN(INSN) ((INSN)->fld[2].rtx) + +/* The body of an insn. */ +#define PATTERN(INSN) ((INSN)->fld[3].rtx) + +/* Code number of instruction, from when it was recognized. + -1 means this instruction has not been recognized yet. */ +#define INSN_CODE(INSN) ((INSN)->fld[4].rtint) + +/* Set up in flow.c; empty before then. + Holds a chain of INSN_LIST rtx's whose first operands point at + previous insns with direct data-flow connections to this one. + That means that those insns set variables whose next use is in this insn. + They are always in the same basic block as this insn. */ +#define LOG_LINKS(INSN) ((INSN)->fld[5].rtx) + +/* 1 if insn has been deleted. */ +#define INSN_DELETED_P(INSN) ((INSN)->volatil) + +/* 1 if insn is a call to a const function. */ +#define CONST_CALL_P(INSN) ((INSN)->unchanging) + +/* 1 if insn is a branch that should not unconditionally execute its + delay slots, i.e., it is an annulled branch. */ +#define INSN_ANNULLED_BRANCH_P(INSN) ((INSN)->unchanging) + +/* 1 if insn is in a delay slot and is from the target of the branch. If + the branch insn has INSN_ANNULLED_BRANCH_P set, this insn should only be + executed if the branch is taken. For annulled branches with this bit + clear, the insn should be executed only if the branch is not taken. */ +#define INSN_FROM_TARGET_P(INSN) ((INSN)->in_struct) + +/* Holds a list of notes on what this insn does to various REGs. + It is a chain of EXPR_LIST rtx's, where the second operand + is the chain pointer and the first operand is the REG being described. + The mode field of the EXPR_LIST contains not a real machine mode + but a value that says what this note says about the REG: + REG_DEAD means that the value in REG dies in this insn (i.e., it is + not needed past this insn). If REG is set in this insn, the REG_DEAD + note may, but need not, be omitted. + REG_INC means that the REG is autoincremented or autodecremented. + REG_EQUIV describes the insn as a whole; it says that the + insn sets a register to a constant value or to be equivalent to + a memory address. If the + register is spilled to the stack then the constant value + should be substituted for it. The contents of the REG_EQUIV + is the constant value or memory address, which may be different + from the source of the SET although it has the same value. + REG_EQUAL is like REG_EQUIV except that the destination + is only momentarily equal to the specified rtx. Therefore, it + cannot be used for substitution; but it can be used for cse. + REG_RETVAL means that this insn copies the return-value of + a library call out of the hard reg for return values. This note + is actually an INSN_LIST and it points to the first insn involved + in setting up arguments for the call. flow.c uses this to delete + the entire library call when its result is dead. + REG_LIBCALL is the inverse of REG_RETVAL: it goes on the first insn + of the library call and points at the one that has the REG_RETVAL. + REG_WAS_0 says that the register set in this insn held 0 before the insn. + The contents of the note is the insn that stored the 0. + If that insn is deleted or patched to a NOTE, the REG_WAS_0 is inoperative. + The REG_WAS_0 note is actually an INSN_LIST, not an EXPR_LIST. + REG_NONNEG means that the register is always nonnegative during + the containing loop. This is used in branches so that decrement and + branch instructions terminating on zero can be matched. There must be + an insn pattern in the md file named `decrement_and_branch_until_zero' + or else this will never be added to any instructions. + REG_NO_CONFLICT means there is no conflict *after this insn* + between the register in the note and the destination of this insn. + REG_UNUSED identifies a register set in this insn and never used. + REG_CC_SETTER and REG_CC_USER link a pair of insns that set and use + CC0, respectively. Normally, these are required to be consecutive insns, + but we permit putting a cc0-setting insn in the delay slot of a branch + as long as only one copy of the insn exists. In that case, these notes + point from one to the other to allow code generation to determine what + any require information and to properly update CC_STATUS. + REG_LABEL points to a CODE_LABEL. Used by non-JUMP_INSNs to + say that the CODE_LABEL contained in the REG_LABEL note is used + by the insn. + REG_DEP_ANTI is used in LOG_LINKS which represent anti (write after read) + dependencies. REG_DEP_OUTPUT is used in LOG_LINKS which represent output + (write after write) dependencies. Data dependencies, which are the only + type of LOG_LINK created by flow, are represented by a 0 reg note kind. */ + +#define REG_NOTES(INSN) ((INSN)->fld[6].rtx) + +/* Don't forget to change reg_note_name in rtl.c. */ +enum reg_note { REG_DEAD = 1, REG_INC = 2, REG_EQUIV = 3, REG_WAS_0 = 4, + REG_EQUAL = 5, REG_RETVAL = 6, REG_LIBCALL = 7, + REG_NONNEG = 8, REG_NO_CONFLICT = 9, REG_UNUSED = 10, + REG_CC_SETTER = 11, REG_CC_USER = 12, REG_LABEL = 13, + REG_DEP_ANTI = 14, REG_DEP_OUTPUT = 15 }; + +/* Define macros to extract and insert the reg-note kind in an EXPR_LIST. */ +#define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK)) +#define PUT_REG_NOTE_KIND(LINK,KIND) PUT_MODE(LINK, (enum machine_mode) (KIND)) + +/* Names for REG_NOTE's in EXPR_LIST insn's. */ + +extern char *reg_note_name[]; +#define GET_REG_NOTE_NAME(MODE) (reg_note_name[(int)(MODE)]) + +/* This field is only present on CALL_INSNs. It holds a chain of EXPR_LIST of + USE and CLOBBER expressions. + USE expressions list the registers filled with arguments that + are passed to the function. + CLOBBER expressions document the registers explicitly clobbered + by this CALL_INSN. + Pseudo registers can not be mentioned in this list. */ +#define CALL_INSN_FUNCTION_USAGE(INSN) ((INSN)->fld[7].rtx) + +/* The label-number of a code-label. The assembler label + is made from `L' and the label-number printed in decimal. + Label numbers are unique in a compilation. */ +#define CODE_LABEL_NUMBER(INSN) ((INSN)->fld[3].rtint) + +#define LINE_NUMBER NOTE + +/* In a NOTE that is a line number, this is a string for the file name + that the line is in. We use the same field to record block numbers + temporarily in NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes. + (We avoid lots of casts between ints and pointers if we use a + different macro for the bock number.) */ + +#define NOTE_SOURCE_FILE(INSN) ((INSN)->fld[3].rtstr) +#define NOTE_BLOCK_NUMBER(INSN) ((INSN)->fld[3].rtint) + +/* In a NOTE that is a line number, this is the line number. + Other kinds of NOTEs are identified by negative numbers here. */ +#define NOTE_LINE_NUMBER(INSN) ((INSN)->fld[4].rtint) + +/* Codes that appear in the NOTE_LINE_NUMBER field + for kinds of notes that are not line numbers. + + Notice that we do not try to use zero here for any of + the special note codes because sometimes the source line + actually can be zero! This happens (for example) when we + are generating code for the per-translation-unit constructor + and destructor routines for some C++ translation unit. + + If you should change any of the following values, or if you + should add a new value here, don't forget to change the + note_insn_name array in rtl.c. */ + +/* This note is used to get rid of an insn + when it isn't safe to patch the insn out of the chain. */ +#define NOTE_INSN_DELETED -1 +#define NOTE_INSN_BLOCK_BEG -2 +#define NOTE_INSN_BLOCK_END -3 +#define NOTE_INSN_LOOP_BEG -4 +#define NOTE_INSN_LOOP_END -5 +/* This kind of note is generated at the end of the function body, + just before the return insn or return label. + In an optimizing compilation it is deleted by the first jump optimization, + after enabling that optimizer to determine whether control can fall + off the end of the function body without a return statement. */ +#define NOTE_INSN_FUNCTION_END -6 +/* This kind of note is generated just after each call to `setjmp', et al. */ +#define NOTE_INSN_SETJMP -7 +/* Generated at the place in a loop that `continue' jumps to. */ +#define NOTE_INSN_LOOP_CONT -8 +/* Generated at the start of a duplicated exit test. */ +#define NOTE_INSN_LOOP_VTOP -9 +/* This marks the point immediately after the last prologue insn. */ +#define NOTE_INSN_PROLOGUE_END -10 +/* This marks the point immediately prior to the first epilogue insn. */ +#define NOTE_INSN_EPILOGUE_BEG -11 +/* Generated in place of user-declared labels when they are deleted. */ +#define NOTE_INSN_DELETED_LABEL -12 +/* This note indicates the start of the real body of the function, + i.e. the point just after all of the parms have been moved into + their homes, etc. */ +#define NOTE_INSN_FUNCTION_BEG -13 + + +#if 0 /* These are not used, and I don't know what they were for. --rms. */ +#define NOTE_DECL_NAME(INSN) ((INSN)->fld[3].rtstr) +#define NOTE_DECL_CODE(INSN) ((INSN)->fld[4].rtint) +#define NOTE_DECL_RTL(INSN) ((INSN)->fld[5].rtx) +#define NOTE_DECL_IDENTIFIER(INSN) ((INSN)->fld[6].rtint) +#define NOTE_DECL_TYPE(INSN) ((INSN)->fld[7].rtint) +#endif /* 0 */ + +/* Names for NOTE insn's other than line numbers. */ + +extern char *note_insn_name[]; +#define GET_NOTE_INSN_NAME(NOTE_CODE) (note_insn_name[-(NOTE_CODE)]) + +/* The name of a label, in case it corresponds to an explicit label + in the input source code. */ +#define LABEL_NAME(LABEL) ((LABEL)->fld[4].rtstr) + +/* In jump.c, each label contains a count of the number + of LABEL_REFs that point at it, so unused labels can be deleted. */ +#define LABEL_NUSES(LABEL) ((LABEL)->fld[5].rtint) + +/* The rest is used instead of the above, in a CODE_LABEL, + if bytecode is being output. + We make the slightly klugy assumption that a LABEL has enough slots + to hold these things. That happens to be true. */ + +/* For static or external objects. */ +#define BYTECODE_LABEL(X) (XEXP ((X), 0)) + +/* For goto labels inside bytecode functions. */ +#define BYTECODE_BC_LABEL(X) (*(struct bc_label **) &XEXP ((X), 1)) + +/* In jump.c, each JUMP_INSN can point to a label that it can jump to, + so that if the JUMP_INSN is deleted, the label's LABEL_NUSES can + be decremented and possibly the label can be deleted. */ +#define JUMP_LABEL(INSN) ((INSN)->fld[7].rtx) + +/* Once basic blocks are found in flow.c, + each CODE_LABEL starts a chain that goes through + all the LABEL_REFs that jump to that label. + The chain eventually winds up at the CODE_LABEL; it is circular. */ +#define LABEL_REFS(LABEL) ((LABEL)->fld[5].rtx) + +/* This is the field in the LABEL_REF through which the circular chain + of references to a particular label is linked. + This chain is set up in flow.c. */ + +#define LABEL_NEXTREF(REF) ((REF)->fld[1].rtx) + +/* Once basic blocks are found in flow.c, + Each LABEL_REF points to its containing instruction with this field. */ + +#define CONTAINING_INSN(RTX) ((RTX)->fld[2].rtx) + +/* For a REG rtx, REGNO extracts the register number. */ + +#define REGNO(RTX) ((RTX)->fld[0].rtint) + +/* For a REG rtx, REG_FUNCTION_VALUE_P is nonzero if the reg + is the current function's return value. */ + +#define REG_FUNCTION_VALUE_P(RTX) ((RTX)->integrated) + +/* 1 in a REG rtx if it corresponds to a variable declared by the user. */ +#define REG_USERVAR_P(RTX) ((RTX)->volatil) + +/* For a CONST_INT rtx, INTVAL extracts the integer. */ + +#define INTVAL(RTX) ((RTX)->fld[0].rtwint) + +/* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of. + SUBREG_WORD extracts the word-number. */ + +#define SUBREG_REG(RTX) ((RTX)->fld[0].rtx) +#define SUBREG_WORD(RTX) ((RTX)->fld[1].rtint) + +/* 1 if the REG contained in SUBREG_REG is already known to be + sign- or zero-extended from the mode of the SUBREG to the mode of + the reg. SUBREG_PROMOTED_UNSIGNED_P gives the signedness of the + extension. + + When used as a LHS, is means that this extension must be done + when assigning to SUBREG_REG. */ + +#define SUBREG_PROMOTED_VAR_P(RTX) ((RTX)->in_struct) +#define SUBREG_PROMOTED_UNSIGNED_P(RTX) ((RTX)->unchanging) + +/* Access various components of an ASM_OPERANDS rtx. */ + +#define ASM_OPERANDS_TEMPLATE(RTX) XSTR ((RTX), 0) +#define ASM_OPERANDS_OUTPUT_CONSTRAINT(RTX) XSTR ((RTX), 1) +#define ASM_OPERANDS_OUTPUT_IDX(RTX) XINT ((RTX), 2) +#define ASM_OPERANDS_INPUT_VEC(RTX) XVEC ((RTX), 3) +#define ASM_OPERANDS_INPUT_CONSTRAINT_VEC(RTX) XVEC ((RTX), 4) +#define ASM_OPERANDS_INPUT(RTX, N) XVECEXP ((RTX), 3, (N)) +#define ASM_OPERANDS_INPUT_LENGTH(RTX) XVECLEN ((RTX), 3) +#define ASM_OPERANDS_INPUT_CONSTRAINT(RTX, N) XSTR (XVECEXP ((RTX), 4, (N)), 0) +#define ASM_OPERANDS_INPUT_MODE(RTX, N) GET_MODE (XVECEXP ((RTX), 4, (N))) +#define ASM_OPERANDS_SOURCE_FILE(RTX) XSTR ((RTX), 5) +#define ASM_OPERANDS_SOURCE_LINE(RTX) XINT ((RTX), 6) + +/* For a MEM rtx, 1 if it's a volatile reference. + Also in an ASM_OPERANDS rtx. */ +#define MEM_VOLATILE_P(RTX) ((RTX)->volatil) + +/* For a MEM rtx, 1 if it refers to a structure or union component. */ +#define MEM_IN_STRUCT_P(RTX) ((RTX)->in_struct) + +/* For a LABEL_REF, 1 means that this reference is to a label outside the + loop containing the reference. */ +#define LABEL_OUTSIDE_LOOP_P(RTX) ((RTX)->in_struct) + +/* For a LABEL_REF, 1 means it is for a nonlocal label. */ +/* Likewise in an EXPR_LIST for a REG_LABEL note. */ +#define LABEL_REF_NONLOCAL_P(RTX) ((RTX)->volatil) + +/* For a CODE_LABEL, 1 means always consider this label to be needed. */ +#define LABEL_PRESERVE_P(RTX) ((RTX)->in_struct) + +/* For a REG, 1 means the register is used only in an exit test of a loop. */ +#define REG_LOOP_TEST_P(RTX) ((RTX)->in_struct) + +/* During sched, for an insn, 1 means that the insn must be scheduled together + with the preceding insn. */ +#define SCHED_GROUP_P(INSN) ((INSN)->in_struct) + +/* During sched, for the LOG_LINKS of an insn, these cache the adjusted + cost of the dependence link. The cost of executing an instruction + may vary based on how the results are used. LINK_COST_ZERO is 1 when + the cost through the link varies and is unchanged (i.e., the link has + zero additional cost). LINK_COST_FREE is 1 when the cost through the + link is zero (i.e., the link makes the cost free). In other cases, + the adjustment to the cost is recomputed each time it is needed. */ +#define LINK_COST_ZERO(X) ((X)->jump) +#define LINK_COST_FREE(X) ((X)->call) + +/* For a SET rtx, SET_DEST is the place that is set + and SET_SRC is the value it is set to. */ +#define SET_DEST(RTX) ((RTX)->fld[0].rtx) +#define SET_SRC(RTX) ((RTX)->fld[1].rtx) + +/* For a TRAP_IF rtx, TRAP_CONDITION is an expression. */ +#define TRAP_CONDITION(RTX) ((RTX)->fld[0].rtx) + +/* 1 in a SYMBOL_REF if it addresses this function's constants pool. */ +#define CONSTANT_POOL_ADDRESS_P(RTX) ((RTX)->unchanging) + +/* Flag in a SYMBOL_REF for machine-specific purposes. */ +#define SYMBOL_REF_FLAG(RTX) ((RTX)->volatil) + +/* 1 means a SYMBOL_REF has been the library function in emit_library_call. */ +#define SYMBOL_REF_USED(RTX) ((RTX)->used) + +/* For an INLINE_HEADER rtx, FIRST_FUNCTION_INSN is the first insn + of the function that is not involved in copying parameters to + pseudo-registers. FIRST_PARM_INSN is the very first insn of + the function, including the parameter copying. + We keep this around in case we must splice + this function into the assembly code at the end of the file. + FIRST_LABELNO is the first label number used by the function (inclusive). + LAST_LABELNO is the last label used by the function (exclusive). + MAX_REGNUM is the largest pseudo-register used by that function. + FUNCTION_ARGS_SIZE is the size of the argument block in the stack. + POPS_ARGS is the number of bytes of input arguments popped by the function + STACK_SLOT_LIST is the list of stack slots. + FUNCTION_FLAGS are where single-bit flags are saved. + OUTGOING_ARGS_SIZE is the size of the largest outgoing stack parameter list. + ORIGINAL_ARG_VECTOR is a vector of the original DECL_RTX values + for the function arguments. + ORIGINAL_DECL_INITIAL is a pointer to the original DECL_INITIAL for the + function. + + We want this to lay down like an INSN. The PREV_INSN field + is always NULL. The NEXT_INSN field always points to the + first function insn of the function being squirreled away. */ + +#define FIRST_FUNCTION_INSN(RTX) ((RTX)->fld[2].rtx) +#define FIRST_PARM_INSN(RTX) ((RTX)->fld[3].rtx) +#define FIRST_LABELNO(RTX) ((RTX)->fld[4].rtint) +#define LAST_LABELNO(RTX) ((RTX)->fld[5].rtint) +#define MAX_PARMREG(RTX) ((RTX)->fld[6].rtint) +#define MAX_REGNUM(RTX) ((RTX)->fld[7].rtint) +#define FUNCTION_ARGS_SIZE(RTX) ((RTX)->fld[8].rtint) +#define POPS_ARGS(RTX) ((RTX)->fld[9].rtint) +#define STACK_SLOT_LIST(RTX) ((RTX)->fld[10].rtx) +#define FUNCTION_FLAGS(RTX) ((RTX)->fld[11].rtint) +#define OUTGOING_ARGS_SIZE(RTX) ((RTX)->fld[12].rtint) +#define ORIGINAL_ARG_VECTOR(RTX) ((RTX)->fld[13].rtvec) +#define ORIGINAL_DECL_INITIAL(RTX) ((RTX)->fld[14].rtx) + +/* In FUNCTION_FLAGS we save some variables computed when emitting the code + for the function and which must be `or'ed into the current flag values when + insns from that function are being inlined. */ + +/* These ought to be an enum, but non-ANSI compilers don't like that. */ +#define FUNCTION_FLAGS_CALLS_ALLOCA 01 +#define FUNCTION_FLAGS_CALLS_SETJMP 02 +#define FUNCTION_FLAGS_RETURNS_STRUCT 04 +#define FUNCTION_FLAGS_RETURNS_PCC_STRUCT 010 +#define FUNCTION_FLAGS_NEEDS_CONTEXT 020 +#define FUNCTION_FLAGS_HAS_NONLOCAL_LABEL 040 +#define FUNCTION_FLAGS_RETURNS_POINTER 0100 +#define FUNCTION_FLAGS_USES_CONST_POOL 0200 +#define FUNCTION_FLAGS_CALLS_LONGJMP 0400 +#define FUNCTION_FLAGS_USES_PIC_OFFSET_TABLE 01000 + +/* Define a macro to look for REG_INC notes, + but save time on machines where they never exist. */ + +/* Don't continue this line--convex cc version 4.1 would lose. */ +#if (defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT) || defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT)) +#define FIND_REG_INC_NOTE(insn, reg) (find_reg_note ((insn), REG_INC, (reg))) +#else +#define FIND_REG_INC_NOTE(insn, reg) 0 +#endif + +/* Indicate whether the machine has any sort of auto increment addressing. + If not, we can avoid checking for REG_INC notes. */ + +/* Don't continue this line--convex cc version 4.1 would lose. */ +#if (defined (HAVE_PRE_INCREMENT) || defined (HAVE_PRE_DECREMENT) || defined (HAVE_POST_INCREMENT) || defined (HAVE_POST_DECREMENT)) +#define AUTO_INC_DEC +#endif + +/* Generally useful functions. */ + +/* The following functions accept a wide integer argument. Rather than + having to cast on every function call, we use a macro instead, that is + defined here and in tree.h. */ + +#ifndef exact_log2 +#define exact_log2(N) exact_log2_wide ((HOST_WIDE_INT) (N)) +#define floor_log2(N) floor_log2_wide ((HOST_WIDE_INT) (N)) +#endif + +#define plus_constant(X,C) plus_constant_wide (X, (HOST_WIDE_INT) (C)) + +#define plus_constant_for_output(X,C) \ + plus_constant_for_output_wide (X, (HOST_WIDE_INT) (C)) + +extern rtx plus_constant_wide PROTO((rtx, HOST_WIDE_INT)); +extern rtx plus_constant_for_output_wide PROTO((rtx, HOST_WIDE_INT)); + +#define GEN_INT(N) gen_rtx (CONST_INT, VOIDmode, (HOST_WIDE_INT) (N)) + +extern rtx bc_gen_rtx (); + +extern rtx gen_rtx PVPROTO((enum rtx_code, + enum machine_mode, ...)); +extern rtvec gen_rtvec PVPROTO((int, ...)); + +extern rtx read_rtx STDIO_PROTO((FILE *)); + +#if 0 +/* At present, don't prototype xrealloc, since all of the callers don't + cast their pointers to char *, and all of the xrealloc's don't use + void * yet. */ +extern char *xmalloc PROTO((size_t)); +extern char *xrealloc PROTO((void *, size_t)); +#else +extern char *xmalloc (); +extern char *xrealloc (); +#endif + +extern char *oballoc PROTO((int)); +extern char *permalloc PROTO((int)); +extern void free PROTO((void *)); +extern rtx rtx_alloc PROTO((RTX_CODE)); +extern rtvec rtvec_alloc PROTO((int)); +extern rtx find_reg_note PROTO((rtx, enum reg_note, rtx)); +extern rtx find_regno_note PROTO((rtx, enum reg_note, int)); +extern int find_reg_fusage PROTO((rtx, enum rtx_code, rtx)); +extern int find_regno_fusage PROTO((rtx, enum rtx_code, int)); +extern HOST_WIDE_INT get_integer_term PROTO((rtx)); +extern rtx get_related_value PROTO((rtx)); +extern rtx single_set PROTO((rtx)); +extern rtx find_last_value PROTO((rtx, rtx *, rtx)); +extern rtx copy_rtx PROTO((rtx)); +extern rtx copy_rtx_if_shared PROTO((rtx)); +extern rtx copy_most_rtx PROTO((rtx, rtx)); +extern rtx replace_rtx PROTO((rtx, rtx, rtx)); +extern rtvec gen_rtvec_v PROTO((int, rtx *)); +extern rtx gen_reg_rtx PROTO((enum machine_mode)); +extern rtx gen_label_rtx PROTO((void)); +extern rtx gen_inline_header_rtx PROTO((rtx, rtx, int, int, int, int, int, int, rtx, int, int, rtvec, rtx)); +extern rtx gen_lowpart_common PROTO((enum machine_mode, rtx)); +extern rtx gen_lowpart PROTO((enum machine_mode, rtx)); +extern rtx gen_lowpart_if_possible PROTO((enum machine_mode, rtx)); +extern rtx gen_highpart PROTO((enum machine_mode, rtx)); +extern rtx gen_realpart PROTO((enum machine_mode, rtx)); +extern rtx gen_imagpart PROTO((enum machine_mode, rtx)); +extern rtx operand_subword PROTO((rtx, int, int, enum machine_mode)); +extern rtx operand_subword_force PROTO((rtx, int, enum machine_mode)); +extern int subreg_lowpart_p PROTO((rtx)); +extern rtx make_safe_from PROTO((rtx, rtx)); +extern rtx memory_address PROTO((enum machine_mode, rtx)); +extern rtx get_insns PROTO((void)); +extern rtx get_last_insn PROTO((void)); +extern rtx get_last_insn_anywhere PROTO((void)); +extern void start_sequence PROTO((void)); +extern void push_to_sequence PROTO((rtx)); +extern void end_sequence PROTO((void)); +extern rtx gen_sequence PROTO((void)); +extern rtx immed_double_const PROTO((HOST_WIDE_INT, HOST_WIDE_INT, enum machine_mode)); +extern rtx force_const_mem PROTO((enum machine_mode, rtx)); +extern rtx force_reg PROTO((enum machine_mode, rtx)); +extern rtx get_pool_constant PROTO((rtx)); +extern enum machine_mode get_pool_mode PROTO((rtx)); +extern int get_pool_offset PROTO((rtx)); +extern rtx simplify_subtraction PROTO((rtx)); +extern rtx assign_stack_local PROTO((enum machine_mode, int, int)); +extern rtx assign_stack_temp PROTO((enum machine_mode, int, int)); +extern rtx protect_from_queue PROTO((rtx, int)); +extern void emit_queue PROTO((void)); +extern rtx emit_move_insn PROTO((rtx, rtx)); +extern rtx emit_insn_before PROTO((rtx, rtx)); +extern rtx emit_jump_insn_before PROTO((rtx, rtx)); +extern rtx emit_call_insn_before PROTO((rtx, rtx)); +extern rtx emit_barrier_before PROTO((rtx)); +extern rtx emit_note_before PROTO((int, rtx)); +extern rtx emit_insn_after PROTO((rtx, rtx)); +extern rtx emit_jump_insn_after PROTO((rtx, rtx)); +extern rtx emit_barrier_after PROTO((rtx)); +extern rtx emit_label_after PROTO((rtx, rtx)); +extern rtx emit_note_after PROTO((int, rtx)); +extern rtx emit_line_note_after PROTO((char *, int, rtx)); +extern rtx emit_insn PROTO((rtx)); +extern rtx emit_insns PROTO((rtx)); +extern rtx emit_insns_before PROTO((rtx, rtx)); +extern rtx emit_jump_insn PROTO((rtx)); +extern rtx emit_call_insn PROTO((rtx)); +extern rtx emit_label PROTO((rtx)); +extern rtx emit_barrier PROTO((void)); +extern rtx emit_line_note PROTO((char *, int)); +extern rtx emit_note PROTO((char *, int)); +extern rtx emit_line_note_force PROTO((char *, int)); +extern rtx make_insn_raw PROTO((rtx)); +extern rtx previous_insn PROTO((rtx)); +extern rtx next_insn PROTO((rtx)); +extern rtx prev_nonnote_insn PROTO((rtx)); +extern rtx next_nonnote_insn PROTO((rtx)); +extern rtx prev_real_insn PROTO((rtx)); +extern rtx next_real_insn PROTO((rtx)); +extern rtx prev_active_insn PROTO((rtx)); +extern rtx next_active_insn PROTO((rtx)); +extern rtx prev_label PROTO((rtx)); +extern rtx next_label PROTO((rtx)); +extern rtx next_cc0_user PROTO((rtx)); +extern rtx prev_cc0_setter PROTO((rtx)); +extern rtx reg_set_last PROTO((rtx, rtx)); +extern rtx next_nondeleted_insn PROTO((rtx)); +extern enum rtx_code reverse_condition PROTO((enum rtx_code)); +extern enum rtx_code swap_condition PROTO((enum rtx_code)); +extern enum rtx_code unsigned_condition PROTO((enum rtx_code)); +extern enum rtx_code signed_condition PROTO((enum rtx_code)); +extern rtx find_equiv_reg PROTO((rtx, rtx, enum reg_class, int, short *, int, enum machine_mode)); +extern rtx squeeze_notes PROTO((rtx, rtx)); +extern rtx delete_insn PROTO((rtx)); +extern void delete_jump PROTO((rtx)); +extern rtx get_label_before PROTO((rtx)); +extern rtx get_label_after PROTO((rtx)); +extern rtx follow_jumps PROTO((rtx)); +extern rtx adj_offsettable_operand PROTO((rtx, int)); +extern rtx try_split PROTO((rtx, rtx, int)); +extern rtx split_insns PROTO((rtx, rtx)); +extern rtx simplify_unary_operation PROTO((enum rtx_code, enum machine_mode, rtx, enum machine_mode)); +extern rtx simplify_binary_operation PROTO((enum rtx_code, enum machine_mode, rtx, rtx)); +extern rtx simplify_ternary_operation PROTO((enum rtx_code, enum machine_mode, enum machine_mode, rtx, rtx, rtx)); +extern rtx simplify_relational_operation PROTO((enum rtx_code, enum machine_mode, rtx, rtx)); +extern rtx nonlocal_label_rtx_list PROTO((void)); +extern rtx gen_move_insn PROTO((rtx, rtx)); +extern rtx gen_jump PROTO((rtx)); +extern rtx gen_beq PROTO((rtx)); +extern rtx gen_bge PROTO((rtx)); +extern rtx gen_ble PROTO((rtx)); +extern rtx eliminate_constant_term PROTO((rtx, rtx *)); +extern rtx expand_complex_abs PROTO((enum machine_mode, rtx, rtx, int)); +extern enum machine_mode choose_hard_reg_mode PROTO((int, int)); + +/* Maximum number of parallel sets and clobbers in any insn in this fn. + Always at least 3, since the combiner could put that many togetherm + and we want this to remain correct for all the remaining passes. */ + +extern int max_parallel; + +extern int asm_noperands PROTO((rtx)); +extern char *decode_asm_operands PROTO((rtx, rtx *, rtx **, char **, enum machine_mode *)); + +extern enum reg_class reg_preferred_class PROTO((int)); +extern enum reg_class reg_alternate_class PROTO((int)); + +extern rtx get_first_nonparm_insn PROTO((void)); + +/* Standard pieces of rtx, to be substituted directly into things. */ +extern rtx pc_rtx; +extern rtx cc0_rtx; +extern rtx const0_rtx; +extern rtx const1_rtx; +extern rtx const2_rtx; +extern rtx constm1_rtx; +extern rtx const_true_rtx; + +extern rtx const_tiny_rtx[3][(int) MAX_MACHINE_MODE]; + +/* Returns a constant 0 rtx in mode MODE. Integer modes are treated the + same as VOIDmode. */ + +#define CONST0_RTX(MODE) (const_tiny_rtx[0][(int) (MODE)]) + +/* Likewise, for the constants 1 and 2. */ + +#define CONST1_RTX(MODE) (const_tiny_rtx[1][(int) (MODE)]) +#define CONST2_RTX(MODE) (const_tiny_rtx[2][(int) (MODE)]) + +/* All references to certain hard regs, except those created + by allocating pseudo regs into them (when that's possible), + go through these unique rtx objects. */ +extern rtx stack_pointer_rtx; +extern rtx frame_pointer_rtx; +extern rtx hard_frame_pointer_rtx; +extern rtx arg_pointer_rtx; +extern rtx pic_offset_table_rtx; +extern rtx struct_value_rtx; +extern rtx struct_value_incoming_rtx; +extern rtx static_chain_rtx; +extern rtx static_chain_incoming_rtx; + +/* If HARD_FRAME_POINTER_REGNUM is defined, then a special dummy reg + is used to represent the frame pointer. This is because the + hard frame pointer and the automatic variables are separated by an amount + that cannot be determined until after register allocation. We can assume + that in this case ELIMINABLE_REGS will be defined, one action of which + will be to eliminate FRAME_POINTER_REGNUM into HARD_FRAME_POINTER_REGNUM. */ +#ifndef HARD_FRAME_POINTER_REGNUM +#define HARD_FRAME_POINTER_REGNUM FRAME_POINTER_REGNUM +#endif + +/* Virtual registers are used during RTL generation to refer to locations into + the stack frame when the actual location isn't known until RTL generation + is complete. The routine instantiate_virtual_regs replaces these with + the proper value, which is normally {frame,arg,stack}_pointer_rtx plus + a constant. */ + +#define FIRST_VIRTUAL_REGISTER (FIRST_PSEUDO_REGISTER) + +/* This points to the first word of the incoming arguments passed on the stack, + either by the caller or by the callee when pretending it was passed by the + caller. */ + +extern rtx virtual_incoming_args_rtx; + +#define VIRTUAL_INCOMING_ARGS_REGNUM (FIRST_VIRTUAL_REGISTER) + +/* If FRAME_GROWS_DOWNWARD, this points to immediately above the first + variable on the stack. Otherwise, it points to the first variable on + the stack. */ + +extern rtx virtual_stack_vars_rtx; + +#define VIRTUAL_STACK_VARS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 1) + +/* This points to the location of dynamically-allocated memory on the stack + immediately after the stack pointer has been adjusted by the amount + desired. */ + +extern rtx virtual_stack_dynamic_rtx; + +#define VIRTUAL_STACK_DYNAMIC_REGNUM ((FIRST_VIRTUAL_REGISTER) + 2) + +/* This points to the location in the stack at which outgoing arguments should + be written when the stack is pre-pushed (arguments pushed using push + insns always use sp). */ + +extern rtx virtual_outgoing_args_rtx; + +#define VIRTUAL_OUTGOING_ARGS_REGNUM ((FIRST_VIRTUAL_REGISTER) + 3) + +#define LAST_VIRTUAL_REGISTER ((FIRST_VIRTUAL_REGISTER) + 3) + +extern rtx find_next_ref PROTO((rtx, rtx)); +extern rtx *find_single_use PROTO((rtx, rtx, rtx *)); + +/* It is hard to write the prototype for expand_expr, since it needs + expr.h to be included for the enumeration. */ + +extern rtx expand_expr (); + +extern rtx output_constant_def PROTO((union tree_node *)); +extern rtx immed_real_const PROTO((union tree_node *)); +extern union tree_node *make_tree PROTO((union tree_node *, rtx)); + +/* Define a default value for STORE_FLAG_VALUE. */ + +#ifndef STORE_FLAG_VALUE +#define STORE_FLAG_VALUE 1 +#endif + +/* Nonzero after end of reload pass. + Set to 1 or 0 by toplev.c. */ + +extern int reload_completed; + +/* Set to 1 while reload_as_needed is operating. + Required by some machines to handle any generated moves differently. */ + +extern int reload_in_progress; + +/* If this is nonzero, we do not bother generating VOLATILE + around volatile memory references, and we are willing to + output indirect addresses. If cse is to follow, we reject + indirect addresses so a useful potential cse is generated; + if it is used only once, instruction combination will produce + the same indirect address eventually. */ +extern int cse_not_expected; + +/* Indexed by pseudo register number, gives the rtx for that pseudo. + Allocated in parallel with regno_pointer_flag. */ +extern rtx *regno_reg_rtx; + +/* Translates rtx code to tree code, for those codes needed by + REAL_ARITHMETIC. The function returns an int because the caller may not + know what `enum tree_code' means. */ + +extern int rtx_to_tree_code PROTO((enum rtx_code)); diff --git a/gnu/usr.bin/cc/include/stack.h b/gnu/usr.bin/cc/include/stack.h new file mode 100644 index 0000000..c5d9a25 --- /dev/null +++ b/gnu/usr.bin/cc/include/stack.h @@ -0,0 +1,41 @@ +/* stack.h - structed access to object stacks + Copyright (C) 1988 Free Software Foundation, Inc. + Contributed by Michael Tiemann (tiemann@cygnus.com). + +This program 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. + +This program 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; if not, write to the Free Software +Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Summary: this file contains additional structures that layer + on top of obstacks for GNU C++. */ + +/* Stack of data placed on obstacks. */ + +struct stack_level +{ + /* Pointer back to previous such level. */ + struct stack_level *prev; + + /* Point to obstack we should return to. */ + struct obstack *obstack; + + /* First place we start putting data. */ + tree *first; + + /* Number of entries we can have from `first'. + Right now we are dumb: if we overflow, abort. */ + int limit; +}; + +struct stack_level *push_stack_level PROTO((struct obstack *, char *, int)); +struct stack_level *pop_stack_level PROTO((struct stack_level *)); diff --git a/gnu/usr.bin/cc/include/tconfig.h b/gnu/usr.bin/cc/include/tconfig.h new file mode 100644 index 0000000..7886724 --- /dev/null +++ b/gnu/usr.bin/cc/include/tconfig.h @@ -0,0 +1,42 @@ +/* Configuration for GNU C-compiler for Intel 80386. + Copyright (C) 1988, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef i386 +#define i386 +#endif + +/* #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/gnu/usr.bin/cc/include/tm.h b/gnu/usr.bin/cc/include/tm.h new file mode 100644 index 0000000..12f7ebc --- /dev/null +++ b/gnu/usr.bin/cc/include/tm.h @@ -0,0 +1,327 @@ +/* Definitions of target machine for GNU compiler for Intel 80386 + running FreeBSD. + Copyright (C) 1988, 1992, 1994 Free Software Foundation, Inc. + Contributed by Poul-Henning Kamp <phk@login.dkuug.dk> + +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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This goes away when the math-emulator is fixed */ +#define TARGET_CPU_DEFAULT 0400 /* TARGET_NO_FANCY_MATH_387 */ + +/* This is tested by i386gas.h. */ +#define YES_UNDERSCORES + +#include "i386/gstabs.h" + +/* Get perform_* macros to build libgcc.a. */ +#include "i386/perform.h" + +#undef CPP_PREDEFINES +#define CPP_PREDEFINES "-Dunix -Di386 -D__FreeBSD__ -D__386BSD__ -Asystem(unix) -Asystem(FreeBSD) -Acpu(i386) -Amachine(i386)" + +#define INCLUDE_DEFAULTS { \ + { "/usr/include", 0 }, \ + { "/usr/include/g++", 1 }, \ + { 0, 0} \ + } + +#define ASM_SPEC " %| %{fpic:-k} %{fPIC:-k}" + +/* Like the default, except no -lg. */ +#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}" + +#define LINK_SPEC \ + "%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*} \ + %{p:-Bstatic} %{pg:-Bstatic} %{Z}" + +#undef SIZE_TYPE +#define SIZE_TYPE "unsigned int" + +#undef PTRDIFF_TYPE +#define PTRDIFF_TYPE "int" + +#undef WCHAR_TYPE +#define WCHAR_TYPE "int" + +#define WCHAR_UNSIGNED 0 + +#undef WCHAR_TYPE_SIZE +#define WCHAR_TYPE_SIZE BITS_PER_WORD + +#define HAVE_ATEXIT + +/* Tell final.c that we don't need a label passed to mcount. */ + +#define NO_PROFILE_DATA + +/* Redefine this to not pass an unused label in %edx. */ + +#undef FUNCTION_PROFILER +#define FUNCTION_PROFILER(FILE, LABELNO) \ +{ \ + if (flag_pic) \ + fprintf (FILE, "\tcall *mcount@GOT(%%ebx)\n"); \ + else \ + fprintf (FILE, "\tcall mcount\n"); \ +} + +#define FUNCTION_PROFILER_EPILOGUE(FILE) \ +{ \ + if (flag_pic) \ + fprintf (FILE, "\tcall *mexitcount@GOT(%%ebx)\n"); \ + else \ + fprintf (FILE, "\tcall mexitcount\n"); \ +} + +/* There are conflicting reports about whether this system uses + a different assembler syntax. wilson@cygnus.com says # is right. */ +#undef COMMENT_BEGIN +#define COMMENT_BEGIN "#" + +#undef ASM_APP_ON +#define ASM_APP_ON "#APP\n" + +#undef ASM_APP_OFF +#define ASM_APP_OFF "#NO_APP\n" + +/* The following macros are stolen from i386v4.h */ +/* These have to be defined to get PIC code correct */ + +/* This is how to output an element of a case-vector that is relative. + This is only used for PIC code. See comments by the `casesi' insn in + i386.md for an explanation of the expression this outputs. */ + +#undef ASM_OUTPUT_ADDR_DIFF_ELT +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \ + fprintf (FILE, "\t.long _GLOBAL_OFFSET_TABLE_+[.-%s%d]\n", LPREFIX, VALUE) + +/* Indicate that jump tables go in the text section. This is + necessary when compiling PIC code. */ + +#define JUMP_TABLES_IN_TEXT_SECTION + +/* Don't default to pcc-struct-return, because gcc is the only compiler, and + we want to retain compatibility with older gcc versions. */ +#define DEFAULT_PCC_STRUCT_RETURN 0 + +/* + * Some imports from svr4.h in support of shared libraries. + * Currently, we need the DECLARE_OBJECT_SIZE stuff. + */ + +/* Define the strings used for the special svr4 .type and .size directives. + These strings generally do not vary from one system running svr4 to + another, but if a given system (e.g. m88k running svr) needs to use + different pseudo-op names for these, they may be overridden in the + file which includes this one. */ + +#define TYPE_ASM_OP ".type" +#define SIZE_ASM_OP ".size" +#define WEAK_ASM_OP ".weak" + +/* The following macro defines the format used to output the second + operand of the .type assembler directive. Different svr4 assemblers + expect various different forms for this operand. The one given here + is just a default. You may need to override it in your machine- + specific tm.h file (depending upon the particulars of your assembler). */ + +#define TYPE_OPERAND_FMT "@%s" + +/* Write the extra assembler code needed to declare a function's result. + Most svr4 assemblers don't require any special declaration of the + result value, but there are exceptions. */ + +#ifndef ASM_DECLARE_RESULT +#define ASM_DECLARE_RESULT(FILE, RESULT) +#endif + +/* These macros generate the special .type and .size directives which + are used to set the corresponding fields of the linker symbol table + entries in an ELF object file under SVR4. These macros also output + the starting labels for the relevant functions/objects. */ + +/* Write the extra assembler code needed to declare a function properly. + Some svr4 assemblers need to also have something extra said about the + function's return value. We allow for that here. */ + +#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \ + do { \ + fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ + assemble_name (FILE, NAME); \ + putc (',', FILE); \ + fprintf (FILE, TYPE_OPERAND_FMT, "function"); \ + putc ('\n', FILE); \ + ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \ + ASM_OUTPUT_LABEL(FILE, NAME); \ + } while (0) + +/* Write the extra assembler code needed to declare an object properly. */ + +#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \ + do { \ + fprintf (FILE, "\t%s\t ", TYPE_ASM_OP); \ + assemble_name (FILE, NAME); \ + putc (',', FILE); \ + fprintf (FILE, TYPE_OPERAND_FMT, "object"); \ + putc ('\n', FILE); \ + size_directive_output = 0; \ + if (!flag_inhibit_size_directive && DECL_SIZE (DECL)) \ + { \ + size_directive_output = 1; \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, NAME); \ + fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ + } \ + ASM_OUTPUT_LABEL(FILE, NAME); \ + } while (0) + +/* Output the size directive for a decl in rest_of_decl_compilation + in the case where we did not do so before the initializer. + Once we find the error_mark_node, we know that the value of + size_directive_output was set + by ASM_DECLARE_OBJECT_NAME when it was run for the same decl. */ + +#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP_LEVEL, AT_END) \ +do { \ + char *name = XSTR (XEXP (DECL_RTL (DECL), 0), 0); \ + if (!flag_inhibit_size_directive && DECL_SIZE (DECL) \ + && ! AT_END && TOP_LEVEL \ + && DECL_INITIAL (DECL) == error_mark_node \ + && !size_directive_output) \ + { \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, name); \ + fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (DECL))); \ + } \ + } while (0) + +/* This is how to declare the size of a function. */ + +#define ASM_DECLARE_FUNCTION_SIZE(FILE, FNAME, DECL) \ + do { \ + if (!flag_inhibit_size_directive) \ + { \ + char label[256]; \ + static int labelno; \ + labelno++; \ + ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \ + ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \ + fprintf (FILE, "\t%s\t ", SIZE_ASM_OP); \ + assemble_name (FILE, (FNAME)); \ + fprintf (FILE, ","); \ + assemble_name (FILE, label); \ + fprintf (FILE, "-"); \ + assemble_name (FILE, (FNAME)); \ + putc ('\n', FILE); \ + } \ + } while (0) + +/* This section copied from i386/osfrose.h */ + +/* A C statement or compound statement to output to FILE some + assembler code to initialize basic-block profiling for the current + object module. This code should call the subroutine + `__bb_init_func' once per object module, passing it as its sole + argument the address of a block allocated in the object module. + + The name of the block is a local symbol made with this statement: + + ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 0); + + Of course, since you are writing the definition of + `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you + can take a short cut in the definition of this macro and use the + name that you know will result. + + The first word of this block is a flag which will be nonzero if the + object module has already been initialized. So test this word + first, and do not call `__bb_init_func' if the flag is nonzero. */ + +#undef FUNCTION_BLOCK_PROFILER +#define FUNCTION_BLOCK_PROFILER(STREAM, LABELNO) \ +do \ + { \ + if (!flag_pic) \ + { \ + fprintf (STREAM, "\tcmpl $0,%sPBX0\n", LPREFIX); \ + fprintf (STREAM, "\tjne 0f\n"); \ + fprintf (STREAM, "\tpushl $%sPBX0\n", LPREFIX); \ + fprintf (STREAM, "\tcall ___bb_init_func\n"); \ + fprintf (STREAM, "0:\n"); \ + } \ + else \ + { \ + fprintf (STREAM, "\tpushl %eax\n"); \ + fprintf (STREAM, "\tmovl %sPBX0@GOT(%ebx),%eax\n"); \ + fprintf (STREAM, "\tcmpl $0,(%eax)\n"); \ + fprintf (STREAM, "\tjne 0f\n"); \ + fprintf (STREAM, "\tpushl %eax\n"); \ + fprintf (STREAM, "\tcall ___bb_init_func@PLT\n"); \ + fprintf (STREAM, "0:\n"); \ + fprintf (STREAM, "\tpopl %eax\n"); \ + } \ + } \ +while (0) + +/* A C statement or compound statement to increment the count + associated with the basic block number BLOCKNO. Basic blocks are + numbered separately from zero within each compilation. The count + associated with block number BLOCKNO is at index BLOCKNO in a + vector of words; the name of this array is a local symbol made + with this statement: + + ASM_GENERATE_INTERNAL_LABEL (BUFFER, "LPBX", 2); + + Of course, since you are writing the definition of + `ASM_GENERATE_INTERNAL_LABEL' as well as that of this macro, you + can take a short cut in the definition of this macro and use the + name that you know will result. */ + +#undef BLOCK_PROFILER +#define BLOCK_PROFILER(STREAM, BLOCKNO) \ +do \ + { \ + if (!flag_pic) \ + fprintf (STREAM, "\tincl %sPBX2+%d\n", LPREFIX, (BLOCKNO)*4); \ + else \ + { \ + fprintf (STREAM, "\tpushl %eax\n"); \ + fprintf (STREAM, "\tmovl %sPBX2@GOT(%ebx),%eax\n", LPREFIX); \ + fprintf (STREAM, "\tincl %d(%eax)\n", (BLOCKNO)*4); \ + fprintf (STREAM, "\tpopl %eax\n"); \ + } \ + } \ +while (0) + +/* This is defined when gcc is compiled in the BSD-directory-tree, and must + * make up for the gap to all the stuff done in the GNU-makefiles. + */ + +#ifdef FREEBSD_NATIVE + +#undef MD_EXEC_PREFIX +#define MD_EXEC_PREFIX "/usr/libexec/" + +#undef STANDARD_STARTFILE_PREFIX +#define STANDARD_STARTFILE_PREFIX "/usr/lib" + +#define DEFAULT_TARGET_MACHINE "i386-unknown-freebsd_1.0" +#define GPLUSPLUS_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include" +#define TOOL_INCLUDE_DIR "/usr/local/i386-unknown-freebsd_1.0/include" +#define GCC_INCLUDE_DIR "/usr/local/lib/gcc-lib/i386-unknown-freebsd_1.0/2.5.8/include" + +#endif /* FREEBSD_NATIVE */ diff --git a/gnu/usr.bin/cc/include/tree.def b/gnu/usr.bin/cc/include/tree.def new file mode 100644 index 0000000..71d6386 --- /dev/null +++ b/gnu/usr.bin/cc/include/tree.def @@ -0,0 +1,695 @@ +/* This file contains the definitions and documentation for the + tree codes used in the GNU C compiler. + Copyright (C) 1987, 1988, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +/* The third argument can be: + "x" for an exceptional code (fits no category). + "t" for a type object code. + "b" for a lexical block. + "c" for codes for constants. + "d" for codes for declarations (also serving as variable refs). + "r" for codes for references to storage. + "<" for codes for comparison expressions. + "1" for codes for unary arithmetic expressions. + "2" for codes for binary arithmetic expressions. + "s" for codes for expressions with inherent side effects. + "e" for codes for other kinds of expressions. */ + +/* For `r', `e', `<', `1', `2', `s' and `x' nodes, + the 4th element is the number of argument slots to allocate. + This determines the size of the tree node object. */ + +/* Any erroneous construct is parsed into a node of this type. + This type of node is accepted without complaint in all contexts + by later parsing activities, to avoid multiple error messages + for one error. + No fields in these nodes are used except the TREE_CODE. */ +DEFTREECODE (ERROR_MARK, "error_mark", "x", 0) + +/* Used to represent a name (such as, in the DECL_NAME of a decl node). + Internally it looks like a STRING_CST node. + There is only one IDENTIFIER_NODE ever made for any particular name. + Use `get_identifier' to get it (or create it, the first time). */ +DEFTREECODE (IDENTIFIER_NODE, "identifier_node", "x", -1) + +/* Used to hold information to identify an operator (or combination + of two operators) considered as a `noun' rather than a `verb'. + The first operand is encoded in the TREE_TYPE field. */ +DEFTREECODE (OP_IDENTIFIER, "op_identifier", "x", 2) + +/* Has the TREE_VALUE and TREE_PURPOSE fields. */ +/* These nodes are made into lists by chaining through the + TREE_CHAIN field. The elements of the list live in the + TREE_VALUE fields, while TREE_PURPOSE fields are occasionally + used as well to get the effect of Lisp association lists. */ +DEFTREECODE (TREE_LIST, "tree_list", "x", 2) + +/* These nodes contain an array of tree nodes. */ +DEFTREECODE (TREE_VEC, "tree_vec", "x", 2) + +/* A symbol binding block. These are arranged in a tree, + where the BLOCK_SUBBLOCKS field contains a chain of subblocks + chained through the BLOCK_CHAIN field. + BLOCK_SUPERCONTEXT points to the parent block. + For a block which represents the outermost scope of a function, it + points to the FUNCTION_DECL node. + BLOCK_VARS points to a chain of decl nodes. + BLOCK_TYPE_TAGS points to a chain of types which have their own names. + BLOCK_CHAIN points to the next BLOCK at the same level. + BLOCK_ABSTRACT_ORIGIN points to the original (abstract) tree node which + this block is an instance of, or else is NULL to indicate that this + block is not an instance of anything else. When non-NULL, the value + could either point to another BLOCK node or it could point to a + FUNCTION_DECL node (e.g. in the case of a block representing the + outermost scope of a particular inlining of a function). + BLOCK_ABSTRACT is non-zero if the block represents an abstract + instance of a block (i.e. one which is nested within an abstract + instance of a inline function. */ +DEFTREECODE (BLOCK, "block", "b", 0) + +/* Each data type is represented by a tree node whose code is one of + the following: */ +/* Each node that represents a data type has a component TYPE_SIZE + containing a tree that is an expression for the size in bits. + The TYPE_MODE contains the machine mode for values of this type. + The TYPE_POINTER_TO field contains a type for a pointer to this type, + or zero if no such has been created yet. + The TYPE_NEXT_VARIANT field is used to chain together types + that are variants made by type modifiers such as "const" and "volatile". + The TYPE_MAIN_VARIANT field, in any member of such a chain, + points to the start of the chain. + The TYPE_NONCOPIED_PARTS field is a list specifying which parts + of an object of this type should *not* be copied by assignment. + The TREE_PURPOSE of each element is the offset of the part + and the TREE_VALUE is the size in bits of the part. + The TYPE_NAME field contains info on the name used in the program + for this type (for GDB symbol table output). It is either a + TYPE_DECL node, for types that are typedefs, or an IDENTIFIER_NODE + in the case of structs, unions or enums that are known with a tag, + or zero for types that have no special name. + The TYPE_CONTEXT for any sort of type which could have a name or + which could have named members (e.g. tagged types in C/C++) will + point to the node which represents the scope of the given type, or + will be NULL_TREE if the type has "file scope". For most types, this + will point to a BLOCK node or a FUNCTION_DECL node, but it could also + point to a FUNCTION_TYPE node (for types whose scope is limited to the + formal parameter list of some function type specification) or it + could point to a RECORD_TYPE, UNION_TYPE or QUAL_UNION_TYPE node + (for C++ "member" types). + For non-tagged-types, TYPE_CONTEXT need not be set to anything in + particular, since any type which is of some type category (e.g. + an array type or a function type) which cannot either have a name + itself or have named members doesn't really have a "scope" per se. + The TREE_CHAIN field is used as a forward-references to names for + ENUMERAL_TYPE, RECORD_TYPE, UNION_TYPE, and QUAL_UNION_TYPE nodes; + see below. */ + +DEFTREECODE (VOID_TYPE, "void_type", "t", 0) /* The void type in C */ + +/* Integer types in all languages, including char in C. + Also used for sub-ranges of other discrete types. + Has components TYPE_MIN_VALUE, TYPE_MAX_VALUE (expressions, inclusive) + and TYPE_PRECISION (number of bits used by this type). + In the case of a subrange type in Pascal, the TREE_TYPE + of this will point at the supertype (another INTEGER_TYPE, + or an ENUMERAL_TYPE, CHAR_TYPE, or BOOLEAN_TYPE). + Otherwise, the TREE_TYPE is zero. */ +DEFTREECODE (INTEGER_TYPE, "integer_type", "t", 0) + +/* C's float and double. Different floating types are distinguished + by machine mode and by the TYPE_SIZE and the TYPE_PRECISION. */ +DEFTREECODE (REAL_TYPE, "real_type", "t", 0) + +/* Complex number types. The TREE_TYPE field is the data type + of the real and imaginary parts. */ +DEFTREECODE (COMPLEX_TYPE, "complex_type", "t", 0) + +/* C enums. The type node looks just like an INTEGER_TYPE node. + The symbols for the values of the enum type are defined by + CONST_DECL nodes, but the type does not point to them; + however, the TYPE_VALUES is a list in which each element's TREE_PURPOSE + is a name and the TREE_VALUE is the value (an INTEGER_CST node). */ +/* A forward reference `enum foo' when no enum named foo is defined yet + has zero (a null pointer) in its TYPE_SIZE. The tag name is in + the TYPE_NAME field. If the type is later defined, the normal + fields are filled in. + RECORD_TYPE, UNION_TYPE, and QUAL_UNION_TYPE forward refs are + treated similarly. */ +DEFTREECODE (ENUMERAL_TYPE, "enumeral_type", "t", 0) + +/* Pascal's boolean type (true or false are the only values); + no special fields needed. */ +DEFTREECODE (BOOLEAN_TYPE, "boolean_type", "t", 0) + +/* CHAR in Pascal; not used in C. + No special fields needed. */ +DEFTREECODE (CHAR_TYPE, "char_type", "t", 0) + +/* All pointer-to-x types have code POINTER_TYPE. + The TREE_TYPE points to the node for the type pointed to. */ +DEFTREECODE (POINTER_TYPE, "pointer_type", "t", 0) + +/* An offset is a pointer relative to an object. + The TREE_TYPE field is the type of the object at the offset. + The TYPE_OFFSET_BASETYPE points to the node for the type of object + that the offset is relative to. */ +DEFTREECODE (OFFSET_TYPE, "offset_type", "t", 0) + +/* A reference is like a pointer except that it is coerced + automatically to the value it points to. Used in C++. */ +DEFTREECODE (REFERENCE_TYPE, "reference_type", "t", 0) + +/* METHOD_TYPE is the type of a function which takes an extra first + argument for "self", which is not present in the declared argument list. + The TREE_TYPE is the return type of the method. The TYPE_METHOD_BASETYPE + is the type of "self". TYPE_ARG_TYPES is the real argument list, which + includes the hidden argument for "self". */ +DEFTREECODE (METHOD_TYPE, "method_type", "t", 0) + +/* Used for Pascal; details not determined right now. */ +DEFTREECODE (FILE_TYPE, "file_type", "t", 0) + +/* Types of arrays. Special fields: + TREE_TYPE Type of an array element. + TYPE_DOMAIN Type to index by. + Its range of values specifies the array length. + TYPE_SEP Expression for units from one elt to the next. + TYPE_SEP_UNIT Number of bits in a unit for previous. + The field TYPE_POINTER_TO (TREE_TYPE (array_type)) is always nonzero + and holds the type to coerce a value of that array type to in C. + TYPE_STRING_FLAG indicates a string (in contrast to an array of chars) + in languages (such as Chill) that make a distinction. */ +/* Array types in C or Pascal */ +DEFTREECODE (ARRAY_TYPE, "array_type", "t", 0) + +/* Types of sets for Pascal. Special fields are the same as + in an array type. The target type is always a boolean type. */ +DEFTREECODE (SET_TYPE, "set_type", "t", 0) + +/* Struct in C, or record in Pascal. */ +/* Special fields: + TYPE_FIELDS chain of FIELD_DECLs for the fields of the struct. + A few may need to be added for Pascal. */ +/* See the comment above, before ENUMERAL_TYPE, for how + forward references to struct tags are handled in C. */ +DEFTREECODE (RECORD_TYPE, "record_type", "t", 0) + +/* Union in C. Like a struct, except that the offsets of the fields + will all be zero. */ +/* See the comment above, before ENUMERAL_TYPE, for how + forward references to union tags are handled in C. */ +DEFTREECODE (UNION_TYPE, "union_type", "t", 0) /* C union type */ + +/* Similar to UNION_TYPE, except that the expressions in DECL_QUALIFIER + in each FIELD_DECL determine what the union contains. The first + field whose DECL_QUALIFIER expression is true is deemed to occupy + the union. */ +DEFTREECODE (QUAL_UNION_TYPE, "qual_union_type", "t", 0) + +/* Type of functions. Special fields: + TREE_TYPE type of value returned. + TYPE_ARG_TYPES list of types of arguments expected. + this list is made of TREE_LIST nodes. + Types of "Procedures" in languages where they are different from functions + have code FUNCTION_TYPE also, but then TREE_TYPE is zero or void type. */ +DEFTREECODE (FUNCTION_TYPE, "function_type", "t", 0) + +/* This is a language-specific kind of type. + Its meaning is defined by the language front end. + layout_type does not know how to lay this out, + so the front-end must do so manually. */ +DEFTREECODE (LANG_TYPE, "lang_type", "t", 0) + +/* Expressions */ + +/* First, the constants. */ + +/* Contents are in TREE_INT_CST_LOW and TREE_INT_CST_HIGH fields, + 32 bits each, giving us a 64 bit constant capability. + Note: constants of type char in Pascal are INTEGER_CST, + and so are pointer constants such as nil in Pascal or NULL in C. + `(int *) 1' in C also results in an INTEGER_CST. */ +DEFTREECODE (INTEGER_CST, "integer_cst", "c", 2) + +/* Contents are in TREE_REAL_CST field. Also there is TREE_CST_RTL. */ +DEFTREECODE (REAL_CST, "real_cst", "c", 3) + +/* Contents are in TREE_REALPART and TREE_IMAGPART fields, + whose contents are other constant nodes. + Also there is TREE_CST_RTL. */ +DEFTREECODE (COMPLEX_CST, "complex_cst", "c", 3) + +/* Contents are TREE_STRING_LENGTH and TREE_STRING_POINTER fields. + Also there is TREE_CST_RTL. */ +DEFTREECODE (STRING_CST, "string_cst", "c", 3) + +/* Declarations. All references to names are represented as ..._DECL nodes. + The decls in one binding context are chained through the TREE_CHAIN field. + Each DECL has a DECL_NAME field which contains an IDENTIFIER_NODE. + (Some decls, most often labels, may have zero as the DECL_NAME). + DECL_CONTEXT points to the node representing the context in which + this declaration has its scope. For FIELD_DECLs, this is the + RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node that the field + is a member of. For VAR_DECL, PARM_DECL, FUNCTION_DECL, LABEL_DECL, + and CONST_DECL nodes, this points to the FUNCTION_DECL for the + containing function, or else yields NULL_TREE if the given decl + has "file scope". + DECL_ABSTRACT_ORIGIN, if non-NULL, points to the original (abstract) + ..._DECL node of which this decl is an (inlined or template expanded) + instance. + The TREE_TYPE field holds the data type of the object, when relevant. + LABEL_DECLs have no data type. For TYPE_DECL, the TREE_TYPE field + contents are the type whose name is being declared. + The DECL_ALIGN, DECL_SIZE, + and DECL_MODE fields exist in decl nodes just as in type nodes. + They are unused in LABEL_DECL, TYPE_DECL and CONST_DECL nodes. + + DECL_OFFSET holds an integer number of bits offset for the location. + DECL_VOFFSET holds an expression for a variable offset; it is + to be multiplied by DECL_VOFFSET_UNIT (an integer). + These fields are relevant only in FIELD_DECLs and PARM_DECLs. + + DECL_INITIAL holds the value to initialize a variable to, + or the value of a constant. For a function, it holds the body + (a node of type BLOCK representing the function's binding contour + and whose body contains the function's statements.) For a LABEL_DECL + in C, it is a flag, nonzero if the label's definition has been seen. + + PARM_DECLs use a special field: + DECL_ARG_TYPE is the type in which the argument is actually + passed, which may be different from its type within the function. + + FUNCTION_DECLs use four special fields: + DECL_ARGUMENTS holds a chain of PARM_DECL nodes for the arguments. + DECL_RESULT holds a RESULT_DECL node for the value of a function, + or it is 0 for a function that returns no value. + (C functions returning void have zero here.) + DECL_RESULT_TYPE holds the type in which the result is actually + returned. This is usually the same as the type of DECL_RESULT, + but (1) it may be a wider integer type and + (2) it remains valid, for the sake of inlining, even after the + function's compilation is done. + DECL_FUNCTION_CODE is a code number that is nonzero for + built-in functions. Its value is an enum built_in_function + that says which built-in function it is. + + DECL_SOURCE_FILE holds a filename string and DECL_SOURCE_LINE + holds a line number. In some cases these can be the location of + a reference, if no definition has been seen. + + DECL_ABSTRACT is non-zero if the decl represents an abstract instance + of a decl (i.e. one which is nested within an abstract instance of a + inline function. */ + +DEFTREECODE (FUNCTION_DECL, "function_decl", "d", 0) +DEFTREECODE (LABEL_DECL, "label_decl", "d", 0) +DEFTREECODE (CONST_DECL, "const_decl", "d", 0) +DEFTREECODE (TYPE_DECL, "type_decl", "d", 0) +DEFTREECODE (VAR_DECL, "var_decl", "d", 0) +DEFTREECODE (PARM_DECL, "parm_decl", "d", 0) +DEFTREECODE (RESULT_DECL, "result_decl", "d", 0) +DEFTREECODE (FIELD_DECL, "field_decl", "d", 0) + +/* References to storage. */ + +/* Value is structure or union component. + Operand 0 is the structure or union (an expression); + operand 1 is the field (a node of type FIELD_DECL). */ +DEFTREECODE (COMPONENT_REF, "component_ref", "r", 2) + +/* Reference to a group of bits within an object. Similar to COMPONENT_REF + except the position is given explicitly rather than via a FIELD_DECL. + Operand 0 is the structure or union expression; + operand 1 is a tree giving the number of bits being referenced; + operand 2 is a tree giving the position of the first referenced bit. + The field can be either a signed or unsigned field; + TREE_UNSIGNED says which. */ +DEFTREECODE (BIT_FIELD_REF, "bit_field_ref", "r", 3) + +/* C unary `*' or Pascal `^'. One operand, an expression for a pointer. */ +DEFTREECODE (INDIRECT_REF, "indirect_ref", "r", 1) + +/* Reference to the contents of an offset + (a value whose type is an OFFSET_TYPE). + Operand 0 is the object within which the offset is taken. + Operand 1 is the offset. */ +DEFTREECODE (OFFSET_REF, "offset_ref", "r", 2) + +/* Pascal `^` on a file. One operand, an expression for the file. */ +DEFTREECODE (BUFFER_REF, "buffer_ref", "r", 1) + +/* Array indexing in languages other than C. + Operand 0 is the array; operand 1 is a list of indices + stored as a chain of TREE_LIST nodes. */ +DEFTREECODE (ARRAY_REF, "array_ref", "r", 2) + +/* Constructor: return an aggregate value made from specified components. + In C, this is used only for structure and array initializers. + The first "operand" is really a pointer to the RTL, + for constant constructors only. + The second operand is a list of component values + made out of a chain of TREE_LIST nodes. */ +DEFTREECODE (CONSTRUCTOR, "constructor", "e", 2) + +/* The expression types are mostly straightforward, + with the fourth argument of DEFTREECODE saying + how many operands there are. + Unless otherwise specified, the operands are expressions. */ + +/* Contains two expressions to compute, one followed by the other. + the first value is ignored. The second one's value is used. */ +DEFTREECODE (COMPOUND_EXPR, "compound_expr", "e", 2) + +/* Assignment expression. Operand 0 is the what to set; 1, the new value. */ +DEFTREECODE (MODIFY_EXPR, "modify_expr", "e", 2) + +/* Initialization expression. Operand 0 is the variable to initialize; + Operand 1 is the initializer. */ +DEFTREECODE (INIT_EXPR, "init_expr", "e", 2) + +/* For TARGET_EXPR, operand 0 is the target of an initialization, + operand 1 is the initializer for the target, + and operand 2 is the cleanup for this node, if any. */ +DEFTREECODE (TARGET_EXPR, "target_expr", "e", 3) + +/* Conditional expression ( ... ? ... : ... in C). + Operand 0 is the condition. + Operand 1 is the then-value. + Operand 2 is the else-value. */ +DEFTREECODE (COND_EXPR, "cond_expr", "e", 3) + +/* Declare local variables, including making RTL and allocating space. + Operand 0 is a chain of VAR_DECL nodes for the variables. + Operand 1 is the body, the expression to be computed using + the variables. The value of operand 1 becomes that of the BIND_EXPR. + Operand 2 is the BLOCK that corresponds to these bindings + for debugging purposes. If this BIND_EXPR is actually expanded, + that sets the TREE_USED flag in the BLOCK. + + The BIND_EXPR is not responsible for informing parsers + about these variables. If the body is coming from the input file, + then the code that creates the BIND_EXPR is also responsible for + informing the parser of the variables. + + If the BIND_EXPR is ever expanded, its TREE_USED flag is set. + This tells the code for debugging symbol tables not to ignore the BIND_EXPR. + If the BIND_EXPR should be output for debugging but will not be expanded, + set the TREE_USED flag by hand. + + In order for the BIND_EXPR to be known at all, the code that creates it + must also install it as a subblock in the tree of BLOCK + nodes for the function. */ +DEFTREECODE (BIND_EXPR, "bind_expr", "e", 3) + +/* Function call. Operand 0 is the function. + Operand 1 is the argument list, a list of expressions + made out of a chain of TREE_LIST nodes. + There is no operand 2. That slot is used for the + CALL_EXPR_RTL macro (see preexpand_calls). */ +DEFTREECODE (CALL_EXPR, "call_expr", "e", 3) + +/* Call a method. Operand 0 is the method, whose type is a METHOD_TYPE. + Operand 1 is the expression for "self". + Operand 2 is the list of explicit arguments. */ +DEFTREECODE (METHOD_CALL_EXPR, "method_call_expr", "e", 4) + +/* Specify a value to compute along with its corresponding cleanup. + Operand 0 argument is an expression whose value needs a cleanup. + Operand 1 is an RTL_EXPR which will eventually represent that value. + Operand 2 is the cleanup expression for the object. + The RTL_EXPR is used in this expression, which is how the expression + manages to act on the proper value. + The cleanup is executed by the first enclosing CLEANUP_POINT_EXPR, if + it exists, otherwise it is the responsibility of the caller to manually + call expand_cleanups_to, as needed. */ +DEFTREECODE (WITH_CLEANUP_EXPR, "with_cleanup_expr", "e", 3) + +/* Specify a cleanup point. + Operand 0 is the expression that has cleanups that we want ensure are + cleaned up. */ +DEFTREECODE (CLEANUP_POINT_EXPR, "cleanup_point_expr", "e", 1) + +/* The following two codes are used in languages that have types where + the position and/or sizes of fields vary from object to object of the + same type, i.e., where some other field in the object contains a value + that is used in the computation of another field's offset or size. + + For example, a record type with a discriminant in Ada is such a type. + This mechanism is also used to create "fat pointers" for unconstrained + array types in Ada; the fat pointer is a structure one of whose fields is + a pointer to the actual array type and the other field is a pointer to a + template, which is a structure containing the bounds of the array. The + bounds in the type pointed to by the first field in the fat pointer refer + to the values in the template. + + These "self-references" are doing using a PLACEHOLDER_EXPR. This is a + node that will later be replaced with the object being referenced. Its type + is that of the object and selects which object to use from a chain of + references (see below). + + When we wish to evaluate a size or offset, we check it is contains a + placeholder. If it does, we construct a WITH_RECORD_EXPR that contains + both the expression we wish to evaluate and an expression within which the + object may be found. The latter expression is the object itself in + the simple case of an Ada record with discriminant, but it can be the + array in the case of an unconstrained array. + + In the latter case, we need the fat pointer, because the bounds of the + array can only be accessed from it. However, we rely here on the fact that + the expression for the array contains the dereference of the fat pointer + that obtained the array pointer. + + Accordingly, when looking for the object to substitute in place of + a PLACEHOLDER_EXPR, we look down the first operand of the expression + passed as the second operand to WITH_RECORD_EXPR until we find something + of the desired type or reach a constant. */ + +/* Denotes a record to later be supplied with a WITH_RECORD_EXPR when + evaluating this expression. The type of this expression is used to + find the record to replace it. */ +DEFTREECODE (PLACEHOLDER_EXPR, "placeholder_expr", "x", 0) + +/* Provide an expression that references a record to be used in place + of a PLACEHOLDER_EXPR. The record to be used is the record within + operand 1 that has the same type as the PLACEHOLDER_EXPR in + operand 0. */ +DEFTREECODE (WITH_RECORD_EXPR, "with_record_expr", "e", 2) + +/* Simple arithmetic. Operands must have the same machine mode + and the value shares that mode. */ +DEFTREECODE (PLUS_EXPR, "plus_expr", "2", 2) +DEFTREECODE (MINUS_EXPR, "minus_expr", "2", 2) +DEFTREECODE (MULT_EXPR, "mult_expr", "2", 2) + +/* Division for integer result that rounds the quotient toward zero. */ +/* Operands must have the same machine mode. + In principle they may be real, but that is not currently supported. + The result is always fixed point, and it has the same type as the + operands if they are fixed point. */ +DEFTREECODE (TRUNC_DIV_EXPR, "trunc_div_expr", "2", 2) + +/* Division for integer result that rounds the quotient toward infinity. */ +DEFTREECODE (CEIL_DIV_EXPR, "ceil_div_expr", "2", 2) + +/* Division for integer result that rounds toward minus infinity. */ +DEFTREECODE (FLOOR_DIV_EXPR, "floor_div_expr", "2", 2) + +/* Division for integer result that rounds toward nearest integer. */ +DEFTREECODE (ROUND_DIV_EXPR, "round_div_expr", "2", 2) + +/* Four kinds of remainder that go with the four kinds of division. */ +DEFTREECODE (TRUNC_MOD_EXPR, "trunc_mod_expr", "2", 2) +DEFTREECODE (CEIL_MOD_EXPR, "ceil_mod_expr", "2", 2) +DEFTREECODE (FLOOR_MOD_EXPR, "floor_mod_expr", "2", 2) +DEFTREECODE (ROUND_MOD_EXPR, "round_mod_expr", "2", 2) + +/* Division for real result. The two operands must have the same type. + In principle they could be integers, but currently only real + operands are supported. The result must have the same type + as the operands. */ +DEFTREECODE (RDIV_EXPR, "rdiv_expr", "2", 2) + +/* Division which is not supposed to need rounding. + Used for pointer subtraction in C. */ +DEFTREECODE (EXACT_DIV_EXPR, "exact_div_expr", "2", 2) + +/* Conversion of real to fixed point: four ways to round, + like the four ways to divide. + CONVERT_EXPR can also be used to convert a real to an integer, + and that is what is used in languages that do not have ways of + specifying which of these is wanted. Maybe these are not needed. */ +DEFTREECODE (FIX_TRUNC_EXPR, "fix_trunc_expr", "1", 1) +DEFTREECODE (FIX_CEIL_EXPR, "fix_ceil_expr", "1", 1) +DEFTREECODE (FIX_FLOOR_EXPR, "fix_floor_expr", "1", 1) +DEFTREECODE (FIX_ROUND_EXPR, "fix_round_expr", "1", 1) + +/* Conversion of an integer to a real. */ +DEFTREECODE (FLOAT_EXPR, "float_expr", "1", 1) + +/* Exponentiation. Operands may have any types; + constraints on value type are not known yet. */ +DEFTREECODE (EXPON_EXPR, "expon_expr", "2", 2) + +/* Unary negation. Value has same type as operand. */ +DEFTREECODE (NEGATE_EXPR, "negate_expr", "1", 1) + +DEFTREECODE (MIN_EXPR, "min_expr", "2", 2) +DEFTREECODE (MAX_EXPR, "max_expr", "2", 2) +DEFTREECODE (ABS_EXPR, "abs_expr", "1", 1) +DEFTREECODE (FFS_EXPR, "ffs_expr", "1", 1) + +/* Shift operations for shift and rotate. + Shift is supposed to mean logical shift if done on an + unsigned type, arithmetic shift on a signed type. + The second operand is the number of bits to + shift by, and must always have mode SImode. + The result has the same mode as the first operand. */ +DEFTREECODE (LSHIFT_EXPR, "alshift_expr", "2", 2) +DEFTREECODE (RSHIFT_EXPR, "arshift_expr", "2", 2) +DEFTREECODE (LROTATE_EXPR, "lrotate_expr", "2", 2) +DEFTREECODE (RROTATE_EXPR, "rrotate_expr", "2", 2) + +/* Bitwise operations. Operands have same mode as result. */ +DEFTREECODE (BIT_IOR_EXPR, "bit_ior_expr", "2", 2) +DEFTREECODE (BIT_XOR_EXPR, "bit_xor_expr", "2", 2) +DEFTREECODE (BIT_AND_EXPR, "bit_and_expr", "2", 2) +DEFTREECODE (BIT_ANDTC_EXPR, "bit_andtc_expr", "2", 2) +DEFTREECODE (BIT_NOT_EXPR, "bit_not_expr", "1", 1) + +/* Combination of boolean values or of integers considered only + as zero or nonzero. ANDIF and ORIF allow the second operand + not to be computed if the value of the expression is determined + from the first operand. AND, OR, and XOR always compute the second + operand whether its value is needed or not (for side effects). */ +DEFTREECODE (TRUTH_ANDIF_EXPR, "truth_andif_expr", "e", 2) +DEFTREECODE (TRUTH_ORIF_EXPR, "truth_orif_expr", "e", 2) +DEFTREECODE (TRUTH_AND_EXPR, "truth_and_expr", "e", 2) +DEFTREECODE (TRUTH_OR_EXPR, "truth_or_expr", "e", 2) +DEFTREECODE (TRUTH_XOR_EXPR, "truth_xor_expr", "e", 2) +DEFTREECODE (TRUTH_NOT_EXPR, "truth_not_expr", "e", 1) + +/* Relational operators. + `EQ_EXPR' and `NE_EXPR' are allowed for any types. + The others are allowed only for integer (or pointer or enumeral) + or real types. + In all cases the operands will have the same type, + and the value is always the type used by the language for booleans. */ +DEFTREECODE (LT_EXPR, "lt_expr", "<", 2) +DEFTREECODE (LE_EXPR, "le_expr", "<", 2) +DEFTREECODE (GT_EXPR, "gt_expr", "<", 2) +DEFTREECODE (GE_EXPR, "ge_expr", "<", 2) +DEFTREECODE (EQ_EXPR, "eq_expr", "<", 2) +DEFTREECODE (NE_EXPR, "ne_expr", "<", 2) + +/* Operations for Pascal sets. Not used now. */ +DEFTREECODE (IN_EXPR, "in_expr", "2", 2) +DEFTREECODE (SET_LE_EXPR, "set_le_expr", "<", 2) +DEFTREECODE (CARD_EXPR, "card_expr", "1", 1) +DEFTREECODE (RANGE_EXPR, "range_expr", "2", 2) + +/* Represents a conversion of type of a value. + All conversions, including implicit ones, must be + represented by CONVERT_EXPR nodes. */ +DEFTREECODE (CONVERT_EXPR, "convert_expr", "1", 1) + +/* Represents a conversion expected to require no code to be generated. */ +DEFTREECODE (NOP_EXPR, "nop_expr", "1", 1) + +/* Value is same as argument, but guaranteed not an lvalue. */ +DEFTREECODE (NON_LVALUE_EXPR, "non_lvalue_expr", "1", 1) + +/* Represents something we computed once and will use multiple times. + First operand is that expression. Second is the function decl + in which the SAVE_EXPR was created. The third operand is the RTL, + nonzero only after the expression has been computed. */ +DEFTREECODE (SAVE_EXPR, "save_expr", "e", 3) + +/* Represents something whose RTL has already been expanded + as a sequence which should be emitted when this expression is expanded. + The first operand is the RTL to emit. It is the first of a chain of insns. + The second is the RTL expression for the result. */ +DEFTREECODE (RTL_EXPR, "rtl_expr", "e", 2) + +/* & in C. Value is the address at which the operand's value resides. + Operand may have any mode. Result mode is Pmode. */ +DEFTREECODE (ADDR_EXPR, "addr_expr", "e", 1) + +/* Non-lvalue reference or pointer to an object. */ +DEFTREECODE (REFERENCE_EXPR, "reference_expr", "e", 1) + +/* Operand is a function constant; result is a function variable value + of typeEPmode. Used only for languages that need static chains. */ +DEFTREECODE (ENTRY_VALUE_EXPR, "entry_value_expr", "e", 1) + +/* Given two real or integer operands of the same type, + returns a complex value of the corresponding complex type. */ +DEFTREECODE (COMPLEX_EXPR, "complex_expr", "2", 2) + +/* Complex conjugate of operand. Used only on complex types. + The value has the same type as the operand. */ +DEFTREECODE (CONJ_EXPR, "conj_expr", "1", 1) + +/* Used only on an operand of complex type, these return + a value of the corresponding component type. */ +DEFTREECODE (REALPART_EXPR, "realpart_expr", "1", 1) +DEFTREECODE (IMAGPART_EXPR, "imagpart_expr", "1", 1) + +/* Nodes for ++ and -- in C. + The second arg is how much to increment or decrement by. + For a pointer, it would be the size of the object pointed to. */ +DEFTREECODE (PREDECREMENT_EXPR, "predecrement_expr", "e", 2) +DEFTREECODE (PREINCREMENT_EXPR, "preincrement_expr", "e", 2) +DEFTREECODE (POSTDECREMENT_EXPR, "postdecrement_expr", "e", 2) +DEFTREECODE (POSTINCREMENT_EXPR, "postincrement_expr", "e", 2) + +/* These types of expressions have no useful value, + and always have side effects. */ + +/* A label definition, encapsulated as a statement. + Operand 0 is the LABEL_DECL node for the label that appears here. + The type should be void and the value should be ignored. */ +DEFTREECODE (LABEL_EXPR, "label_expr", "s", 1) + +/* GOTO. Operand 0 is a LABEL_DECL node. + The type should be void and the value should be ignored. */ +DEFTREECODE (GOTO_EXPR, "goto_expr", "s", 1) + +/* RETURN. Evaluates operand 0, then returns from the current function. + Presumably that operand is an assignment that stores into the + RESULT_DECL that hold the value to be returned. + The operand may be null. + The type should be void and the value should be ignored. */ +DEFTREECODE (RETURN_EXPR, "return_expr", "s", 1) + +/* Exit the inner most loop conditionally. Operand 0 is the condition. + The type should be void and the value should be ignored. */ +DEFTREECODE (EXIT_EXPR, "exit_expr", "s", 1) + +/* A loop. Operand 0 is the body of the loop. + It must contain an EXIT_EXPR or is an infinite loop. + The type should be void and the value should be ignored. */ +DEFTREECODE (LOOP_EXPR, "loop_expr", "s", 1) + +/* +Local variables: +mode:c +version-control: t +End: +*/ diff --git a/gnu/usr.bin/cc/include/tree.h b/gnu/usr.bin/cc/include/tree.h new file mode 100644 index 0000000..dbe5ff9 --- /dev/null +++ b/gnu/usr.bin/cc/include/tree.h @@ -0,0 +1,1638 @@ +/* Front-end tree definitions for GNU compiler. + Copyright (C) 1989, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "machmode.h" + +#ifndef RTX_CODE +struct rtx_def; +#endif + +/* Codes of tree nodes */ + +#define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM, + +enum tree_code { +#include "tree.def" + + LAST_AND_UNUSED_TREE_CODE /* A convenient way to get a value for + NUM_TREE_CODE. */ +}; + +#undef DEFTREECODE + +/* Number of tree codes. */ +#define NUM_TREE_CODES ((int)LAST_AND_UNUSED_TREE_CODE) + +/* Indexed by enum tree_code, contains a character which is + `<' for a comparison expression, `1', for a unary arithmetic + expression, `2' for a binary arithmetic expression, `e' for + other types of expressions, `r' for a reference, `c' for a + constant, `d' for a decl, `t' for a type, `s' for a statement, + and `x' for anything else (TREE_LIST, IDENTIFIER, etc). */ + +extern char **tree_code_type; +#define TREE_CODE_CLASS(CODE) (*tree_code_type[(int) (CODE)]) + +/* Number of argument-words in each kind of tree-node. */ + +extern int *tree_code_length; + +/* Names of tree components. */ + +extern char **tree_code_name; + +/* Codes that identify the various built in functions + so that expand_call can identify them quickly. */ + +enum built_in_function +{ + NOT_BUILT_IN, + BUILT_IN_ALLOCA, + BUILT_IN_ABS, + BUILT_IN_FABS, + BUILT_IN_LABS, + BUILT_IN_FFS, + BUILT_IN_DIV, + BUILT_IN_LDIV, + BUILT_IN_FFLOOR, + BUILT_IN_FCEIL, + BUILT_IN_FMOD, + BUILT_IN_FREM, + BUILT_IN_MEMCPY, + BUILT_IN_MEMCMP, + BUILT_IN_MEMSET, + BUILT_IN_STRCPY, + BUILT_IN_STRCMP, + BUILT_IN_STRLEN, + BUILT_IN_FSQRT, + BUILT_IN_SIN, + BUILT_IN_COS, + BUILT_IN_GETEXP, + BUILT_IN_GETMAN, + BUILT_IN_SAVEREGS, + BUILT_IN_CLASSIFY_TYPE, + BUILT_IN_NEXT_ARG, + BUILT_IN_ARGS_INFO, + BUILT_IN_CONSTANT_P, + BUILT_IN_FRAME_ADDRESS, + BUILT_IN_RETURN_ADDRESS, + BUILT_IN_CALLER_RETURN_ADDRESS, + BUILT_IN_APPLY_ARGS, + BUILT_IN_APPLY, + BUILT_IN_RETURN, + + /* C++ extensions */ + BUILT_IN_NEW, + BUILT_IN_VEC_NEW, + BUILT_IN_DELETE, + BUILT_IN_VEC_DELETE, + + /* Upper bound on non-language-specific builtins. */ + END_BUILTINS +}; + +/* The definition of tree nodes fills the next several pages. */ + +/* A tree node can represent a data type, a variable, an expression + or a statement. Each node has a TREE_CODE which says what kind of + thing it represents. Some common codes are: + INTEGER_TYPE -- represents a type of integers. + ARRAY_TYPE -- represents a type of pointer. + VAR_DECL -- represents a declared variable. + INTEGER_CST -- represents a constant integer value. + PLUS_EXPR -- represents a sum (an expression). + + As for the contents of a tree node: there are some fields + that all nodes share. Each TREE_CODE has various special-purpose + fields as well. The fields of a node are never accessed directly, + always through accessor macros. */ + +/* This type is used everywhere to refer to a tree node. */ + +typedef union tree_node *tree; + +/* Every kind of tree node starts with this structure, + so all nodes have these fields. + + See the accessor macros, defined below, for documentation of the fields. */ + +struct tree_common +{ + union tree_node *chain; + union tree_node *type; +#ifdef ONLY_INT_FIELDS + unsigned int code : 8; +#else + enum tree_code code : 8; +#endif + + unsigned side_effects_flag : 1; + unsigned constant_flag : 1; + unsigned permanent_flag : 1; + unsigned addressable_flag : 1; + unsigned volatile_flag : 1; + unsigned readonly_flag : 1; + unsigned unsigned_flag : 1; + unsigned asm_written_flag: 1; + + unsigned used_flag : 1; + unsigned raises_flag : 1; + unsigned static_flag : 1; + unsigned public_flag : 1; + unsigned private_flag : 1; + unsigned protected_flag : 1; + + unsigned lang_flag_0 : 1; + unsigned lang_flag_1 : 1; + unsigned lang_flag_2 : 1; + unsigned lang_flag_3 : 1; + unsigned lang_flag_4 : 1; + unsigned lang_flag_5 : 1; + unsigned lang_flag_6 : 1; + /* There is room for two more flags. */ +}; + +/* Define accessors for the fields that all tree nodes have + (though some fields are not used for all kinds of nodes). */ + +/* The tree-code says what kind of node it is. + Codes are defined in tree.def. */ +#define TREE_CODE(NODE) ((enum tree_code) (NODE)->common.code) +#define TREE_SET_CODE(NODE, VALUE) ((NODE)->common.code = (int) (VALUE)) + +/* In all nodes that are expressions, this is the data type of the expression. + In POINTER_TYPE nodes, this is the type that the pointer points to. + In ARRAY_TYPE nodes, this is the type of the elements. */ +#define TREE_TYPE(NODE) ((NODE)->common.type) + +/* Nodes are chained together for many purposes. + Types are chained together to record them for being output to the debugger + (see the function `chain_type'). + Decls in the same scope are chained together to record the contents + of the scope. + Statement nodes for successive statements used to be chained together. + Often lists of things are represented by TREE_LIST nodes that + are chained together. */ + +#define TREE_CHAIN(NODE) ((NODE)->common.chain) + +/* Given an expression as a tree, strip any NON_LVALUE_EXPRs and NOP_EXPRs + that don't change the machine mode. */ + +#define STRIP_NOPS(EXP) \ + while ((TREE_CODE (EXP) == NOP_EXPR \ + || TREE_CODE (EXP) == CONVERT_EXPR \ + || TREE_CODE (EXP) == NON_LVALUE_EXPR) \ + && (TYPE_MODE (TREE_TYPE (EXP)) \ + == TYPE_MODE (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \ + (EXP) = TREE_OPERAND (EXP, 0); + +/* Like STRIP_NOPS, but don't alter the TREE_TYPE either. */ + +#define STRIP_TYPE_NOPS(EXP) \ + while ((TREE_CODE (EXP) == NOP_EXPR \ + || TREE_CODE (EXP) == CONVERT_EXPR \ + || TREE_CODE (EXP) == NON_LVALUE_EXPR) \ + && (TREE_TYPE (EXP) \ + == TREE_TYPE (TREE_OPERAND (EXP, 0)))) \ + (EXP) = TREE_OPERAND (EXP, 0); + +/* Nonzero if TYPE represents an integral type. Note that we do not + include COMPLEX types here. */ + +#define INTEGRAL_TYPE_P(TYPE) \ + (TREE_CODE (TYPE) == INTEGER_TYPE || TREE_CODE (TYPE) == ENUMERAL_TYPE \ + || TREE_CODE (TYPE) == BOOLEAN_TYPE || TREE_CODE (TYPE) == CHAR_TYPE) + +/* Nonzero if TYPE represents a floating-point type, including complex + floating-point types. */ + +#define FLOAT_TYPE_P(TYPE) \ + (TREE_CODE (TYPE) == REAL_TYPE \ + || (TREE_CODE (TYPE) == COMPLEX_TYPE \ + && TREE_CODE (TREE_TYPE (TYPE)) == REAL_TYPE)) + +/* Nonzero if TYPE represents an aggregate (multi-component) type. */ + +#define AGGREGATE_TYPE_P(TYPE) \ + (TREE_CODE (TYPE) == ARRAY_TYPE || TREE_CODE (TYPE) == RECORD_TYPE \ + || TREE_CODE (TYPE) == UNION_TYPE || TREE_CODE (TYPE) == QUAL_UNION_TYPE \ + || TREE_CODE (TYPE) == SET_TYPE) + +/* Define many boolean fields that all tree nodes have. */ + +/* In VAR_DECL nodes, nonzero means address of this is needed. + So it cannot be in a register. + In a FUNCTION_DECL, nonzero means its address is needed. + So it must be compiled even if it is an inline function. + In CONSTRUCTOR nodes, it means object constructed must be in memory. + In LABEL_DECL nodes, it means a goto for this label has been seen + from a place outside all binding contours that restore stack levels. + In ..._TYPE nodes, it means that objects of this type must + be fully addressable. This means that pieces of this + object cannot go into register parameters, for example. + In IDENTIFIER_NODEs, this means that some extern decl for this name + had its address taken. That matters for inline functions. */ +#define TREE_ADDRESSABLE(NODE) ((NODE)->common.addressable_flag) + +/* In a VAR_DECL, nonzero means allocate static storage. + In a FUNCTION_DECL, nonzero if function has been defined. + In a CONSTRUCTOR, nonzero means allocate static storage. */ +#define TREE_STATIC(NODE) ((NODE)->common.static_flag) + +/* In a CONVERT_EXPR, NOP_EXPR or COMPOUND_EXPR, this means the node was + made implicitly and should not lead to an "unused value" warning. */ +#define TREE_NO_UNUSED_WARNING(NODE) ((NODE)->common.static_flag) + +/* Nonzero for a TREE_LIST or TREE_VEC node means that the derivation + chain is via a `virtual' declaration. */ +#define TREE_VIA_VIRTUAL(NODE) ((NODE)->common.static_flag) + +/* In an INTEGER_CST, REAL_CST, or COMPLEX_CST, this means there was an + overflow in folding. This is distinct from TREE_OVERFLOW because ANSI C + requires a diagnostic when overflows occur in constant expressions. */ +#define TREE_CONSTANT_OVERFLOW(NODE) ((NODE)->common.static_flag) + +/* In an IDENTIFIER_NODE, this means that assemble_name was called with + this string as an argument. */ +#define TREE_SYMBOL_REFERENCED(NODE) ((NODE)->common.static_flag) + +/* In an INTEGER_CST, REAL_CST, of COMPLEX_CST, this means there was an + overflow in folding, and no warning has been issued for this subexpression. + TREE_OVERFLOW implies TREE_CONSTANT_OVERFLOW, but not vice versa. */ +#define TREE_OVERFLOW(NODE) ((NODE)->common.public_flag) + +/* In a VAR_DECL or FUNCTION_DECL, + nonzero means name is to be accessible from outside this module. + In an identifier node, nonzero means an external declaration + accessible from outside this module was previously seen + for this name in an inner scope. */ +#define TREE_PUBLIC(NODE) ((NODE)->common.public_flag) + +/* Nonzero for TREE_LIST or TREE_VEC node means that the path to the + base class is via a `public' declaration, which preserves public + fields from the base class as public. */ +#define TREE_VIA_PUBLIC(NODE) ((NODE)->common.public_flag) + +/* Ditto, for `private' declarations. */ +#define TREE_VIA_PRIVATE(NODE) ((NODE)->common.private_flag) + +/* Nonzero for TREE_LIST node means that the path to the + base class is via a `protected' declaration, which preserves + protected fields from the base class as protected. + OVERLOADED. */ +#define TREE_VIA_PROTECTED(NODE) ((NODE)->common.protected_flag) + +/* In any expression, nonzero means it has side effects or reevaluation + of the whole expression could produce a different value. + This is set if any subexpression is a function call, a side effect + or a reference to a volatile variable. + In a ..._DECL, this is set only if the declaration said `volatile'. */ +#define TREE_SIDE_EFFECTS(NODE) ((NODE)->common.side_effects_flag) + +/* Nonzero means this expression is volatile in the C sense: + its address should be of type `volatile WHATEVER *'. + In other words, the declared item is volatile qualified. + This is used in _DECL nodes and _REF nodes. + + In a ..._TYPE node, means this type is volatile-qualified. + But use TYPE_VOLATILE instead of this macro when the node is a type, + because eventually we may make that a different bit. + + If this bit is set in an expression, so is TREE_SIDE_EFFECTS. */ +#define TREE_THIS_VOLATILE(NODE) ((NODE)->common.volatile_flag) + +/* In a VAR_DECL, PARM_DECL or FIELD_DECL, or any kind of ..._REF node, + nonzero means it may not be the lhs of an assignment. + In a ..._TYPE node, means this type is const-qualified + (but the macro TYPE_READONLY should be used instead of this macro + when the node is a type). */ +#define TREE_READONLY(NODE) ((NODE)->common.readonly_flag) + +/* Value of expression is constant. + Always appears in all ..._CST nodes. + May also appear in an arithmetic expression, an ADDR_EXPR or a CONSTRUCTOR + if the value is constant. */ +#define TREE_CONSTANT(NODE) ((NODE)->common.constant_flag) + +/* Nonzero means permanent node; + node will continue to exist for the entire compiler run. + Otherwise it will be recycled at the end of the function. */ +#define TREE_PERMANENT(NODE) ((NODE)->common.permanent_flag) + +/* In INTEGER_TYPE or ENUMERAL_TYPE nodes, means an unsigned type. + In FIELD_DECL nodes, means an unsigned bit field. + The same bit is used in functions as DECL_BUILT_IN_NONANSI. */ +#define TREE_UNSIGNED(NODE) ((NODE)->common.unsigned_flag) + +/* Nonzero in a VAR_DECL means assembler code has been written. + Nonzero in a FUNCTION_DECL means that the function has been compiled. + This is interesting in an inline function, since it might not need + to be compiled separately. + Nonzero in a RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE or ENUMERAL_TYPE + if the sdb debugging info for the type has been written. + In a BLOCK node, nonzero if reorder_blocks has already seen this block. */ +#define TREE_ASM_WRITTEN(NODE) ((NODE)->common.asm_written_flag) + +/* Nonzero in a _DECL if the name is used in its scope. + Nonzero in an expr node means inhibit warning if value is unused. + In IDENTIFIER_NODEs, this means that some extern decl for this name + was used. */ +#define TREE_USED(NODE) ((NODE)->common.used_flag) + +/* Nonzero for a tree node whose evaluation could result + in the raising of an exception. Not implemented yet. */ +#define TREE_RAISES(NODE) ((NODE)->common.raises_flag) + +/* Used in classes in C++. */ +#define TREE_PRIVATE(NODE) ((NODE)->common.private_flag) +/* Used in classes in C++. + In a BLOCK node, this is BLOCK_HANDLER_BLOCK. */ +#define TREE_PROTECTED(NODE) ((NODE)->common.protected_flag) + +/* These flags are available for each language front end to use internally. */ +#define TREE_LANG_FLAG_0(NODE) ((NODE)->common.lang_flag_0) +#define TREE_LANG_FLAG_1(NODE) ((NODE)->common.lang_flag_1) +#define TREE_LANG_FLAG_2(NODE) ((NODE)->common.lang_flag_2) +#define TREE_LANG_FLAG_3(NODE) ((NODE)->common.lang_flag_3) +#define TREE_LANG_FLAG_4(NODE) ((NODE)->common.lang_flag_4) +#define TREE_LANG_FLAG_5(NODE) ((NODE)->common.lang_flag_5) +#define TREE_LANG_FLAG_6(NODE) ((NODE)->common.lang_flag_6) + +/* Define additional fields and accessors for nodes representing constants. */ + +/* In an INTEGER_CST node. These two together make a 2-word integer. + If the data type is signed, the value is sign-extended to 2 words + even though not all of them may really be in use. + In an unsigned constant shorter than 2 words, the extra bits are 0. */ +#define TREE_INT_CST_LOW(NODE) ((NODE)->int_cst.int_cst_low) +#define TREE_INT_CST_HIGH(NODE) ((NODE)->int_cst.int_cst_high) + +#define INT_CST_LT(A, B) \ +(TREE_INT_CST_HIGH (A) < TREE_INT_CST_HIGH (B) \ + || (TREE_INT_CST_HIGH (A) == TREE_INT_CST_HIGH (B) \ + && ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (A) \ + < (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (B)))) + +#define INT_CST_LT_UNSIGNED(A, B) \ +(((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (A) \ + < (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (B)) \ + || (((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (A) \ + == (unsigned HOST_WIDE_INT ) TREE_INT_CST_HIGH (B)) \ + && (((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (A) \ + < (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (B))))) + +struct tree_int_cst +{ + char common[sizeof (struct tree_common)]; + HOST_WIDE_INT int_cst_low; + HOST_WIDE_INT int_cst_high; +}; + +/* In REAL_CST, STRING_CST, COMPLEX_CST nodes, and CONSTRUCTOR nodes, + and generally in all kinds of constants that could + be given labels (rather than being immediate). */ + +#define TREE_CST_RTL(NODE) ((NODE)->real_cst.rtl) + +/* In a REAL_CST node. */ +/* We can represent a real value as either a `double' or a string. + Strings don't allow for any optimization, but they do allow + for cross-compilation. */ + +#define TREE_REAL_CST(NODE) ((NODE)->real_cst.real_cst) + +#include "real.h" + +struct tree_real_cst +{ + char common[sizeof (struct tree_common)]; + struct rtx_def *rtl; /* acts as link to register transfer language + (rtl) info */ + REAL_VALUE_TYPE real_cst; +}; + +/* In a STRING_CST */ +#define TREE_STRING_LENGTH(NODE) ((NODE)->string.length) +#define TREE_STRING_POINTER(NODE) ((NODE)->string.pointer) + +struct tree_string +{ + char common[sizeof (struct tree_common)]; + struct rtx_def *rtl; /* acts as link to register transfer language + (rtl) info */ + int length; + char *pointer; +}; + +/* In a COMPLEX_CST node. */ +#define TREE_REALPART(NODE) ((NODE)->complex.real) +#define TREE_IMAGPART(NODE) ((NODE)->complex.imag) + +struct tree_complex +{ + char common[sizeof (struct tree_common)]; + struct rtx_def *rtl; /* acts as link to register transfer language + (rtl) info */ + union tree_node *real; + union tree_node *imag; +}; + +/* Define fields and accessors for some special-purpose tree nodes. */ + +#define IDENTIFIER_LENGTH(NODE) ((NODE)->identifier.length) +#define IDENTIFIER_POINTER(NODE) ((NODE)->identifier.pointer) + +struct tree_identifier +{ + char common[sizeof (struct tree_common)]; + int length; + char *pointer; +}; + +/* In a TREE_LIST node. */ +#define TREE_PURPOSE(NODE) ((NODE)->list.purpose) +#define TREE_VALUE(NODE) ((NODE)->list.value) + +struct tree_list +{ + char common[sizeof (struct tree_common)]; + union tree_node *purpose; + union tree_node *value; +}; + +/* In a TREE_VEC node. */ +#define TREE_VEC_LENGTH(NODE) ((NODE)->vec.length) +#define TREE_VEC_ELT(NODE,I) ((NODE)->vec.a[I]) +#define TREE_VEC_END(NODE) (&((NODE)->vec.a[(NODE)->vec.length])) + +struct tree_vec +{ + char common[sizeof (struct tree_common)]; + int length; + union tree_node *a[1]; +}; + +/* Define fields and accessors for some nodes that represent expressions. */ + +/* In a SAVE_EXPR node. */ +#define SAVE_EXPR_CONTEXT(NODE) TREE_OPERAND(NODE, 1) +#define SAVE_EXPR_RTL(NODE) (*(struct rtx_def **) &(NODE)->exp.operands[2]) + +/* In a RTL_EXPR node. */ +#define RTL_EXPR_SEQUENCE(NODE) (*(struct rtx_def **) &(NODE)->exp.operands[0]) +#define RTL_EXPR_RTL(NODE) (*(struct rtx_def **) &(NODE)->exp.operands[1]) + +/* In a CALL_EXPR node. */ +#define CALL_EXPR_RTL(NODE) (*(struct rtx_def **) &(NODE)->exp.operands[2]) + +/* In a CONSTRUCTOR node. */ +#define CONSTRUCTOR_ELTS(NODE) TREE_OPERAND (NODE, 1) + +/* In ordinary expression nodes. */ +#define TREE_OPERAND(NODE, I) ((NODE)->exp.operands[I]) +#define TREE_COMPLEXITY(NODE) ((NODE)->exp.complexity) + +struct tree_exp +{ + char common[sizeof (struct tree_common)]; + int complexity; + union tree_node *operands[1]; +}; + +/* In a BLOCK node. */ +#define BLOCK_VARS(NODE) ((NODE)->block.vars) +#define BLOCK_TYPE_TAGS(NODE) ((NODE)->block.type_tags) +#define BLOCK_SUBBLOCKS(NODE) ((NODE)->block.subblocks) +#define BLOCK_SUPERCONTEXT(NODE) ((NODE)->block.supercontext) +/* Note: when changing this, make sure to find the places + that use chainon or nreverse. */ +#define BLOCK_CHAIN(NODE) TREE_CHAIN (NODE) +#define BLOCK_ABSTRACT_ORIGIN(NODE) ((NODE)->block.abstract_origin) +#define BLOCK_ABSTRACT(NODE) ((NODE)->block.abstract_flag) +#define BLOCK_END_NOTE(NODE) ((NODE)->block.end_note) + +/* Nonzero means that this block is prepared to handle exceptions + listed in the BLOCK_VARS slot. */ +#define BLOCK_HANDLER_BLOCK(NODE) ((NODE)->block.handler_block_flag) + +struct tree_block +{ + char common[sizeof (struct tree_common)]; + + unsigned handler_block_flag : 1; + unsigned abstract_flag : 1; + + union tree_node *vars; + union tree_node *type_tags; + union tree_node *subblocks; + union tree_node *supercontext; + union tree_node *abstract_origin; + struct rtx_def *end_note; +}; + +/* Define fields and accessors for nodes representing data types. */ + +/* See tree.def for documentation of the use of these fields. + Look at the documentation of the various ..._TYPE tree codes. */ + +#define TYPE_UID(NODE) ((NODE)->type.uid) +#define TYPE_SIZE(NODE) ((NODE)->type.size) +#define TYPE_MODE(NODE) ((NODE)->type.mode) +#define TYPE_VALUES(NODE) ((NODE)->type.values) +#define TYPE_DOMAIN(NODE) ((NODE)->type.values) +#define TYPE_FIELDS(NODE) ((NODE)->type.values) +#define TYPE_METHODS(NODE) ((NODE)->type.maxval) +#define TYPE_VFIELD(NODE) ((NODE)->type.minval) +#define TYPE_ARG_TYPES(NODE) ((NODE)->type.values) +#define TYPE_METHOD_BASETYPE(NODE) ((NODE)->type.maxval) +#define TYPE_OFFSET_BASETYPE(NODE) ((NODE)->type.maxval) +#define TYPE_POINTER_TO(NODE) ((NODE)->type.pointer_to) +#define TYPE_REFERENCE_TO(NODE) ((NODE)->type.reference_to) +#define TYPE_MIN_VALUE(NODE) ((NODE)->type.minval) +#define TYPE_MAX_VALUE(NODE) ((NODE)->type.maxval) +#define TYPE_PRECISION(NODE) ((NODE)->type.precision) +#define TYPE_PARSE_INFO(NODE) ((NODE)->type.parse_info) +#define TYPE_SYMTAB_ADDRESS(NODE) ((NODE)->type.symtab.address) +#define TYPE_SYMTAB_POINTER(NODE) ((NODE)->type.symtab.pointer) +#define TYPE_NAME(NODE) ((NODE)->type.name) +#define TYPE_NEXT_VARIANT(NODE) ((NODE)->type.next_variant) +#define TYPE_MAIN_VARIANT(NODE) ((NODE)->type.main_variant) +#define TYPE_BINFO(NODE) ((NODE)->type.binfo) +#define TYPE_NONCOPIED_PARTS(NODE) ((NODE)->type.noncopied_parts) +#define TYPE_CONTEXT(NODE) ((NODE)->type.context) +#define TYPE_OBSTACK(NODE) ((NODE)->type.obstack) +#define TYPE_LANG_SPECIFIC(NODE) ((NODE)->type.lang_specific) + +/* A TREE_LIST of IDENTIFIER nodes of the attributes that apply + to this type. */ +#define TYPE_ATTRIBUTES(NODE) ((NODE)->type.attributes) + +/* The alignment necessary for objects of this type. + The value is an int, measured in bits. */ +#define TYPE_ALIGN(NODE) ((NODE)->type.align) + +#define TYPE_STUB_DECL(NODE) (TREE_CHAIN (NODE)) + +/* In a RECORD_TYPE, UNION_TYPE or QUAL_UNION_TYPE, it means the type + has BLKmode only because it lacks the alignment requirement for + its size. */ +#define TYPE_NO_FORCE_BLK(NODE) ((NODE)->type.no_force_blk_flag) + +/* Nonzero in a type considered volatile as a whole. */ +#define TYPE_VOLATILE(NODE) ((NODE)->common.volatile_flag) + +/* Means this type is const-qualified. */ +#define TYPE_READONLY(NODE) ((NODE)->common.readonly_flag) + +/* These flags are available for each language front end to use internally. */ +#define TYPE_LANG_FLAG_0(NODE) ((NODE)->type.lang_flag_0) +#define TYPE_LANG_FLAG_1(NODE) ((NODE)->type.lang_flag_1) +#define TYPE_LANG_FLAG_2(NODE) ((NODE)->type.lang_flag_2) +#define TYPE_LANG_FLAG_3(NODE) ((NODE)->type.lang_flag_3) +#define TYPE_LANG_FLAG_4(NODE) ((NODE)->type.lang_flag_4) +#define TYPE_LANG_FLAG_5(NODE) ((NODE)->type.lang_flag_5) +#define TYPE_LANG_FLAG_6(NODE) ((NODE)->type.lang_flag_6) + +/* If set in an ARRAY_TYPE, indicates a string type (for languages + that distinguish string from array of char). + If set in a SET_TYPE, indicates a bitstring type. */ +#define TYPE_STRING_FLAG(NODE) ((NODE)->type.string_flag) + +/* Indicates that objects of this type must be initialized by calling a + function when they are created. */ +#define TYPE_NEEDS_CONSTRUCTING(NODE) ((NODE)->type.needs_constructing_flag) + +struct tree_type +{ + char common[sizeof (struct tree_common)]; + union tree_node *values; + union tree_node *size; + union tree_node *attributes; + unsigned uid; + + unsigned char precision; +#ifdef ONLY_INT_FIELDS + int mode : 8; +#else + enum machine_mode mode : 8; +#endif + + unsigned string_flag : 1; + unsigned no_force_blk_flag : 1; + unsigned needs_constructing_flag : 1; + unsigned lang_flag_0 : 1; + unsigned lang_flag_1 : 1; + unsigned lang_flag_2 : 1; + unsigned lang_flag_3 : 1; + unsigned lang_flag_4 : 1; + unsigned lang_flag_5 : 1; + unsigned lang_flag_6 : 1; + /* room for 6 more bits */ + + unsigned int align; + union tree_node *pointer_to; + union tree_node *reference_to; + int parse_info; + union {int address; char *pointer; } symtab; + union tree_node *name; + union tree_node *minval; + union tree_node *maxval; + union tree_node *next_variant; + union tree_node *main_variant; + union tree_node *binfo; + union tree_node *noncopied_parts; + union tree_node *context; + struct obstack *obstack; + /* Points to a structure whose details depend on the language in use. */ + struct lang_type *lang_specific; +}; + +/* Define accessor macros for information about type inheritance + and basetypes. + + A "basetype" means a particular usage of a data type for inheritance + in another type. Each such basetype usage has its own "binfo" + object to describe it. The binfo object is a TREE_VEC node. + + Inheritance is represented by the binfo nodes allocated for a + given type. For example, given types C and D, such that D is + inherited by C, 3 binfo nodes will be allocated: one for describing + the binfo properties of C, similarly one for D, and one for + describing the binfo properties of D as a base type for C. + Thus, given a pointer to class C, one can get a pointer to the binfo + of D acting as a basetype for C by looking at C's binfo's basetypes. */ + +/* The actual data type node being inherited in this basetype. */ +#define BINFO_TYPE(NODE) TREE_TYPE (NODE) + +/* The offset where this basetype appears in its containing type. + BINFO_OFFSET slot holds the offset (in bytes) + from the base of the complete object to the base of the part of the + object that is allocated on behalf of this `type'. + This is always 0 except when there is multiple inheritance. */ + +#define BINFO_OFFSET(NODE) TREE_VEC_ELT ((NODE), 1) +#define TYPE_BINFO_OFFSET(NODE) BINFO_OFFSET (TYPE_BINFO (NODE)) +#define BINFO_OFFSET_ZEROP(NODE) (BINFO_OFFSET (NODE) == integer_zero_node) + +/* The virtual function table belonging to this basetype. Virtual + function tables provide a mechanism for run-time method dispatching. + The entries of a virtual function table are language-dependent. */ + +#define BINFO_VTABLE(NODE) TREE_VEC_ELT ((NODE), 2) +#define TYPE_BINFO_VTABLE(NODE) BINFO_VTABLE (TYPE_BINFO (NODE)) + +/* The virtual functions in the virtual function table. This is + a TREE_LIST that is used as an initial approximation for building + a virtual function table for this basetype. */ +#define BINFO_VIRTUALS(NODE) TREE_VEC_ELT ((NODE), 3) +#define TYPE_BINFO_VIRTUALS(NODE) BINFO_VIRTUALS (TYPE_BINFO (NODE)) + +/* A vector of additional binfos for the types inherited by this basetype. + + If this basetype describes type D as inherited in C, + and if the basetypes of D are E anf F, + then this vector contains binfos for inheritance of E and F by C. + + ??? This could probably be done by just allocating the + base types at the end of this TREE_VEC (instead of using + another TREE_VEC). This would simplify the calculation + of how many basetypes a given type had. */ +#define BINFO_BASETYPES(NODE) TREE_VEC_ELT ((NODE), 4) +#define TYPE_BINFO_BASETYPES(NODE) TREE_VEC_ELT (TYPE_BINFO (NODE), 4) + +/* For a BINFO record describing an inheritance, this yields a pointer + to the artificial FIELD_DECL node which contains the "virtual base + class pointer" for the given inheritance. */ + +#define BINFO_VPTR_FIELD(NODE) TREE_VEC_ELT ((NODE), 5) + +/* Accessor macro to get to the Nth basetype of this basetype. */ +#define BINFO_BASETYPE(NODE,N) TREE_VEC_ELT (BINFO_BASETYPES (NODE), (N)) +#define TYPE_BINFO_BASETYPE(NODE,N) BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (NODE)), (N))) + +/* Slot used to build a chain that represents a use of inheritance. + For example, if X is derived from Y, and Y is derived from Z, + then this field can be used to link the binfo node for X to + the binfo node for X's Y to represent the use of inheritance + from X to Y. Similarly, this slot of the binfo node for X's Y + can point to the Z from which Y is inherited (in X's inheritance + hierarchy). In this fashion, one can represent and traverse specific + uses of inheritance using the binfo nodes themselves (instead of + consing new space pointing to binfo nodes). + It is up to the language-dependent front-ends to maintain + this information as necessary. */ +#define BINFO_INHERITANCE_CHAIN(NODE) TREE_VEC_ELT ((NODE), 0) + +/* Define fields and accessors for nodes representing declared names. */ + +/* This is the name of the object as written by the user. + It is an IDENTIFIER_NODE. */ +#define DECL_NAME(NODE) ((NODE)->decl.name) +/* This is the name of the object as the assembler will see it + (but before any translations made by ASM_OUTPUT_LABELREF). + Often this is the same as DECL_NAME. + It is an IDENTIFIER_NODE. */ +#define DECL_ASSEMBLER_NAME(NODE) ((NODE)->decl.assembler_name) +/* Records the section name in a section attribute. Used to pass + the name from decl_attributes to make_function_rtl and make_decl_rtl. */ +#define DECL_SECTION_NAME(NODE) ((NODE)->decl.section_name) +/* For FIELD_DECLs, this is the + RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node that the field is + a member of. For VAR_DECL, PARM_DECL, FUNCTION_DECL, LABEL_DECL, + and CONST_DECL nodes, this points to the FUNCTION_DECL for the + containing function, or else yields NULL_TREE if the given decl has "file scope". */ +#define DECL_CONTEXT(NODE) ((NODE)->decl.context) +#define DECL_FIELD_CONTEXT(NODE) ((NODE)->decl.context) +/* In a FIELD_DECL, this is the field position, counting in bits, + of the bit closest to the beginning of the structure. */ +#define DECL_FIELD_BITPOS(NODE) ((NODE)->decl.arguments) +/* In a FIELD_DECL, this indicates whether the field was a bit-field and + if so, the type that was originally specified for it. + TREE_TYPE may have been modified (in finish_struct). */ +#define DECL_BIT_FIELD_TYPE(NODE) ((NODE)->decl.result) +/* In FUNCTION_DECL, a chain of ..._DECL nodes. */ +/* VAR_DECL and PARM_DECL reserve the arguments slot + for language-specific uses. */ +#define DECL_ARGUMENTS(NODE) ((NODE)->decl.arguments) +/* In FUNCTION_DECL, holds the decl for the return value. */ +#define DECL_RESULT(NODE) ((NODE)->decl.result) +/* In PARM_DECL, holds the type as written (perhaps a function or array). */ +#define DECL_ARG_TYPE_AS_WRITTEN(NODE) ((NODE)->decl.result) +/* For a FUNCTION_DECL, holds the tree of BINDINGs. + For a VAR_DECL, holds the initial value. + For a PARM_DECL, not used--default + values for parameters are encoded in the type of the function, + not in the PARM_DECL slot. */ +#define DECL_INITIAL(NODE) ((NODE)->decl.initial) +/* For a PARM_DECL, records the data type used to pass the argument, + which may be different from the type seen in the program. */ +#define DECL_ARG_TYPE(NODE) ((NODE)->decl.initial) /* In PARM_DECL. */ +/* For a FIELD_DECL in a QUAL_UNION_TYPE, records the expression, which + if nonzero, indicates that the field occupies the type. */ +#define DECL_QUALIFIER(NODE) ((NODE)->decl.initial) +/* These two fields describe where in the source code the declaration was. */ +#define DECL_SOURCE_FILE(NODE) ((NODE)->decl.filename) +#define DECL_SOURCE_LINE(NODE) ((NODE)->decl.linenum) +/* Holds the size of the datum, as a tree expression. + Need not be constant. */ +#define DECL_SIZE(NODE) ((NODE)->decl.size) +/* Holds the alignment required for the datum. */ +#define DECL_ALIGN(NODE) ((NODE)->decl.frame_size.u) +/* Holds the machine mode corresponding to the declaration of a variable or + field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a + FIELD_DECL. */ +#define DECL_MODE(NODE) ((NODE)->decl.mode) +/* Holds the RTL expression for the value of a variable or function. If + PROMOTED_MODE is defined, the mode of this expression may not be same + as DECL_MODE. In that case, DECL_MODE contains the mode corresponding + to the variable's data type, while the mode + of DECL_RTL is the mode actually used to contain the data. */ +#define DECL_RTL(NODE) ((NODE)->decl.rtl) +/* For PARM_DECL, holds an RTL for the stack slot or register + where the data was actually passed. */ +#define DECL_INCOMING_RTL(NODE) ((NODE)->decl.saved_insns.r) +/* For FUNCTION_DECL, if it is inline, holds the saved insn chain. */ +#define DECL_SAVED_INSNS(NODE) ((NODE)->decl.saved_insns.r) +/* For FUNCTION_DECL, if it is inline, + holds the size of the stack frame, as an integer. */ +#define DECL_FRAME_SIZE(NODE) ((NODE)->decl.frame_size.i) +/* For FUNCTION_DECL, if it is built-in, + this identifies which built-in operation it is. */ +#define DECL_FUNCTION_CODE(NODE) ((NODE)->decl.frame_size.f) +#define DECL_SET_FUNCTION_CODE(NODE,VAL) ((NODE)->decl.frame_size.f = (VAL)) +/* For a FIELD_DECL, holds the size of the member as an integer. */ +#define DECL_FIELD_SIZE(NODE) ((NODE)->decl.saved_insns.i) + +/* The DECL_VINDEX is used for FUNCTION_DECLS in two different ways. + Before the struct containing the FUNCTION_DECL is laid out, + DECL_VINDEX may point to a FUNCTION_DECL in a base class which + is the FUNCTION_DECL which this FUNCTION_DECL will replace as a virtual + function. When the class is laid out, this pointer is changed + to an INTEGER_CST node which is suitable for use as an index + into the virtual function table. */ +#define DECL_VINDEX(NODE) ((NODE)->decl.vindex) +/* For FIELD_DECLS, DECL_FCONTEXT is the *first* baseclass in + which this FIELD_DECL is defined. This information is needed when + writing debugging information about vfield and vbase decls for C++. */ +#define DECL_FCONTEXT(NODE) ((NODE)->decl.vindex) + +/* Every ..._DECL node gets a unique number. */ +#define DECL_UID(NODE) ((NODE)->decl.uid) + +/* For any sort of a ..._DECL node, this points to the original (abstract) + decl node which this decl is an instance of, or else it is NULL indicating + that this decl is not an instance of some other decl. */ +#define DECL_ABSTRACT_ORIGIN(NODE) ((NODE)->decl.abstract_origin) + +/* Nonzero for any sort of ..._DECL node means this decl node represents + an inline instance of some original (abstract) decl from an inline function; + suppress any warnings about shadowing some other variable. */ +#define DECL_FROM_INLINE(NODE) (DECL_ABSTRACT_ORIGIN (NODE) != (tree) 0) + +/* Nonzero if a _DECL means that the name of this decl should be ignored + for symbolic debug purposes. */ +#define DECL_IGNORED_P(NODE) ((NODE)->decl.ignored_flag) + +/* Nonzero for a given ..._DECL node means that this node represents an + "abstract instance" of the given declaration (e.g. in the original + declaration of an inline function). When generating symbolic debugging + information, we musn't try to generate any address information for nodes + marked as "abstract instances" because we don't actually generate + any code or allocate any data space for such instances. */ +#define DECL_ABSTRACT(NODE) ((NODE)->decl.abstract_flag) + +/* Nonzero if a _DECL means that no warnings should be generated just + because this decl is unused. */ +#define DECL_IN_SYSTEM_HEADER(NODE) ((NODE)->decl.in_system_header_flag) + +/* Nonzero for a given ..._DECL node means that this node should be + put in .common, if possible. If a DECL_INITIAL is given, and it + is not error_mark_node, then the decl cannot be put in .common. */ +#define DECL_COMMON(NODE) ((NODE)->decl.common_flag) + +/* Language-specific decl information. */ +#define DECL_LANG_SPECIFIC(NODE) ((NODE)->decl.lang_specific) + +/* In a VAR_DECL or FUNCTION_DECL, + nonzero means external reference: + do not allocate storage, and refer to a definition elsewhere. */ +#define DECL_EXTERNAL(NODE) ((NODE)->decl.external_flag) + +/* In a TYPE_DECL + nonzero means the detail info about this type is not dumped into stabs. + Instead it will generate cross reference ('x') of names. + This uses the same flag as DECL_EXTERNAL. */ +#define TYPE_DECL_SUPPRESS_DEBUG(NODE) ((NODE)->decl.external_flag) + + +/* In VAR_DECL and PARM_DECL nodes, nonzero means declared `register'. + In LABEL_DECL nodes, nonzero means that an error message about + jumping into such a binding contour has been printed for this label. */ +#define DECL_REGISTER(NODE) ((NODE)->decl.regdecl_flag) +/* In a FIELD_DECL, indicates this field should be bit-packed. */ +#define DECL_PACKED(NODE) ((NODE)->decl.regdecl_flag) + +/* Nonzero in a ..._DECL means this variable is ref'd from a nested function. + For VAR_DECL nodes, PARM_DECL nodes, and FUNCTION_DECL nodes. + + For LABEL_DECL nodes, nonzero if nonlocal gotos to the label are permitted. + + Also set in some languages for variables, etc., outside the normal + lexical scope, such as class instance variables. */ +#define DECL_NONLOCAL(NODE) ((NODE)->decl.nonlocal_flag) + +/* Nonzero in a FUNCTION_DECL means this function can be substituted + where it is called. */ +#define DECL_INLINE(NODE) ((NODE)->decl.inline_flag) + +/* Nonzero in a FUNCTION_DECL means this is a built-in function + that is not specified by ansi C and that users are supposed to be allowed + to redefine for any purpose whatever. */ +#define DECL_BUILT_IN_NONANSI(NODE) ((NODE)->common.unsigned_flag) + +/* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed + specially. */ +#define DECL_BIT_FIELD(NODE) ((NODE)->decl.bit_field_flag) +/* In a LABEL_DECL, nonzero means label was defined inside a binding + contour that restored a stack level and which is now exited. */ +#define DECL_TOO_LATE(NODE) ((NODE)->decl.bit_field_flag) +/* In a FUNCTION_DECL, nonzero means a built in function. */ +#define DECL_BUILT_IN(NODE) ((NODE)->decl.bit_field_flag) +/* In a VAR_DECL that's static, + nonzero if the space is in the text section. */ +#define DECL_IN_TEXT_SECTION(NODE) ((NODE)->decl.bit_field_flag) + +/* Used in VAR_DECLs to indicate that the variable is a vtable. + It is also used in FIELD_DECLs for vtable pointers. */ +#define DECL_VIRTUAL_P(NODE) ((NODE)->decl.virtual_flag) + +/* Used to indicate that the linkage status of this DECL is not yet known, + so it should not be output now. */ +#define DECL_DEFER_OUTPUT(NODE) ((NODE)->decl.defer_output) + +/* Additional flags for language-specific uses. */ +#define DECL_LANG_FLAG_0(NODE) ((NODE)->decl.lang_flag_0) +#define DECL_LANG_FLAG_1(NODE) ((NODE)->decl.lang_flag_1) +#define DECL_LANG_FLAG_2(NODE) ((NODE)->decl.lang_flag_2) +#define DECL_LANG_FLAG_3(NODE) ((NODE)->decl.lang_flag_3) +#define DECL_LANG_FLAG_4(NODE) ((NODE)->decl.lang_flag_4) +#define DECL_LANG_FLAG_5(NODE) ((NODE)->decl.lang_flag_5) +#define DECL_LANG_FLAG_6(NODE) ((NODE)->decl.lang_flag_6) +#define DECL_LANG_FLAG_7(NODE) ((NODE)->decl.lang_flag_7) + +struct tree_decl +{ + char common[sizeof (struct tree_common)]; + char *filename; + int linenum; + union tree_node *size; + unsigned int uid; +#ifdef ONLY_INT_FIELDS + int mode : 8; +#else + enum machine_mode mode : 8; +#endif + + unsigned external_flag : 1; + unsigned nonlocal_flag : 1; + unsigned regdecl_flag : 1; + unsigned inline_flag : 1; + unsigned bit_field_flag : 1; + unsigned virtual_flag : 1; + unsigned ignored_flag : 1; + unsigned abstract_flag : 1; + + unsigned in_system_header_flag : 1; + unsigned common_flag : 1; + unsigned defer_output : 1; + /* room for five more */ + + unsigned lang_flag_0 : 1; + unsigned lang_flag_1 : 1; + unsigned lang_flag_2 : 1; + unsigned lang_flag_3 : 1; + unsigned lang_flag_4 : 1; + unsigned lang_flag_5 : 1; + unsigned lang_flag_6 : 1; + unsigned lang_flag_7 : 1; + + union tree_node *name; + union tree_node *context; + union tree_node *arguments; + union tree_node *result; + union tree_node *initial; + union tree_node *abstract_origin; + union tree_node *assembler_name; + union tree_node *section_name; + struct rtx_def *rtl; /* acts as link to register transfer language + (rtl) info */ + /* For a FUNCTION_DECL, if inline, this is the size of frame needed. + If built-in, this is the code for which built-in function. + For other kinds of decls, this is DECL_ALIGN. */ + union { + int i; + unsigned int u; + enum built_in_function f; + } frame_size; + /* For FUNCTION_DECLs: points to insn that constitutes its definition + on the permanent obstack. For any other kind of decl, this is the + alignment. */ + union { + struct rtx_def *r; + int i; + } saved_insns; + union tree_node *vindex; + /* Points to a structure whose details depend on the language in use. */ + struct lang_decl *lang_specific; +}; + +/* Define the overall contents of a tree node. + It may be any of the structures declared above + for various types of node. */ + +union tree_node +{ + struct tree_common common; + struct tree_int_cst int_cst; + struct tree_real_cst real_cst; + struct tree_string string; + struct tree_complex complex; + struct tree_identifier identifier; + struct tree_decl decl; + struct tree_type type; + struct tree_list list; + struct tree_vec vec; + struct tree_exp exp; + struct tree_block block; + }; + +/* Add prototype support. */ +#ifndef PROTO +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define PROTO(ARGS) ARGS +#else +#define PROTO(ARGS) () +#endif +#endif + +#ifndef VPROTO +#ifdef __STDC__ +#define PVPROTO(ARGS) ARGS +#define VPROTO(ARGS) ARGS +#define VA_START(va_list,var) va_start(va_list,var) +#else +#define PVPROTO(ARGS) () +#define VPROTO(ARGS) (va_alist) va_dcl +#define VA_START(va_list,var) va_start(va_list) +#endif +#endif + +#ifndef STDIO_PROTO +#ifdef BUFSIZ +#define STDIO_PROTO(ARGS) PROTO(ARGS) +#else +#define STDIO_PROTO(ARGS) () +#endif +#endif + +#define NULL_TREE (tree) NULL + +/* Define a generic NULL if one hasn't already been defined. */ + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef GENERIC_PTR +#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__) +#define GENERIC_PTR void * +#else +#define GENERIC_PTR char * +#endif +#endif + +#ifndef NULL_PTR +#define NULL_PTR ((GENERIC_PTR)0) +#endif + +/* The following functions accept a wide integer argument. Rather than + having to cast on every function call, we use a macro instead, that is + defined here and in rtl.h. */ + +#ifndef exact_log2 +#define exact_log2(N) exact_log2_wide ((HOST_WIDE_INT) (N)) +#define floor_log2(N) floor_log2_wide ((HOST_WIDE_INT) (N)) +#endif + +#if 0 +/* At present, don't prototype xrealloc, since all of the callers don't + cast their pointers to char *, and all of the xrealloc's don't use + void * yet. */ +extern char *xmalloc PROTO((size_t)); +extern char *xrealloc PROTO((void *, size_t)); +#else +extern char *xmalloc (); +extern char *xrealloc (); +#endif + +extern char *oballoc PROTO((int)); +extern char *permalloc PROTO((int)); +extern char *savealloc PROTO((int)); +extern void free PROTO((void *)); + +/* Lowest level primitive for allocating a node. + The TREE_CODE is the only argument. Contents are initialized + to zero except for a few of the common fields. */ + +extern tree make_node PROTO((enum tree_code)); + +/* Make a copy of a node, with all the same contents except + for TREE_PERMANENT. (The copy is permanent + iff nodes being made now are permanent.) */ + +extern tree copy_node PROTO((tree)); + +/* Make a copy of a chain of TREE_LIST nodes. */ + +extern tree copy_list PROTO((tree)); + +/* Make a TREE_VEC. */ + +extern tree make_tree_vec PROTO((int)); + +/* Return the (unique) IDENTIFIER_NODE node for a given name. + The name is supplied as a char *. */ + +extern tree get_identifier PROTO((char *)); + +/* Construct various types of nodes. */ + +#define build_int_2(LO,HI) \ + build_int_2_wide ((HOST_WIDE_INT) (LO), (HOST_WIDE_INT) (HI)) + +extern tree build PVPROTO((enum tree_code, tree, ...)); +extern tree build_nt PVPROTO((enum tree_code, ...)); +extern tree build_parse_node PVPROTO((enum tree_code, ...)); + +extern tree build_int_2_wide PROTO((HOST_WIDE_INT, HOST_WIDE_INT)); +extern tree build_real PROTO((tree, REAL_VALUE_TYPE)); +extern tree build_real_from_int_cst PROTO((tree, tree)); +extern tree build_complex PROTO((tree, tree)); +extern tree build_string PROTO((int, char *)); +extern tree build1 PROTO((enum tree_code, tree, tree)); +extern tree build_tree_list PROTO((tree, tree)); +extern tree build_decl_list PROTO((tree, tree)); +extern tree build_decl PROTO((enum tree_code, tree, tree)); +extern tree build_block PROTO((tree, tree, tree, tree, tree)); + +/* Construct various nodes representing data types. */ + +extern tree make_signed_type PROTO((int)); +extern tree make_unsigned_type PROTO((int)); +extern tree signed_or_unsigned_type PROTO((int, tree)); +extern void fixup_unsigned_type PROTO((tree)); +extern tree build_pointer_type PROTO((tree)); +extern tree build_reference_type PROTO((tree)); +extern tree build_index_type PROTO((tree)); +extern tree build_index_2_type PROTO((tree, tree)); +extern tree build_array_type PROTO((tree, tree)); +extern tree build_function_type PROTO((tree, tree)); +extern tree build_method_type PROTO((tree, tree)); +extern tree build_offset_type PROTO((tree, tree)); +extern tree build_complex_type PROTO((tree)); +extern tree array_type_nelts PROTO((tree)); + +extern tree value_member PROTO((tree, tree)); +extern tree purpose_member PROTO((tree, tree)); +extern tree binfo_member PROTO((tree, tree)); +extern int attribute_list_equal PROTO((tree, tree)); +extern int attribute_list_contained PROTO((tree, tree)); +extern int tree_int_cst_equal PROTO((tree, tree)); +extern int tree_int_cst_lt PROTO((tree, tree)); +extern int tree_int_cst_sgn PROTO((tree)); +extern int index_type_equal PROTO((tree, tree)); + +/* From expmed.c. Since rtl.h is included after tree.h, we can't + put the prototype here. Rtl.h does declare the prototype if + tree.h had been included. */ + +extern tree make_tree (); + +/* Return a type like TTYPE except that its TYPE_ATTRIBUTES + is ATTRIBUTE. + + Such modified types already made are recorded so that duplicates + are not made. */ + +extern tree build_type_attribute_variant PROTO((tree, tree)); + +/* Given a type node TYPE, and CONSTP and VOLATILEP, return a type + for the same kind of data as TYPE describes. + Variants point to the "main variant" (which has neither CONST nor VOLATILE) + via TYPE_MAIN_VARIANT, and it points to a chain of other variants + so that duplicate variants are never made. + Only main variants should ever appear as types of expressions. */ + +extern tree build_type_variant PROTO((tree, int, int)); + +/* Make a copy of a type node. */ + +extern tree build_type_copy PROTO((tree)); + +/* Given a ..._TYPE node, calculate the TYPE_SIZE, TYPE_SIZE_UNIT, + TYPE_ALIGN and TYPE_MODE fields. + If called more than once on one node, does nothing except + for the first time. */ + +extern void layout_type PROTO((tree)); + +/* Given a hashcode and a ..._TYPE node (for which the hashcode was made), + return a canonicalized ..._TYPE node, so that duplicates are not made. + How the hash code is computed is up to the caller, as long as any two + callers that could hash identical-looking type nodes agree. */ + +extern tree type_hash_canon PROTO((int, tree)); + +/* Given a VAR_DECL, PARM_DECL, RESULT_DECL or FIELD_DECL node, + calculates the DECL_SIZE, DECL_SIZE_UNIT, DECL_ALIGN and DECL_MODE + fields. Call this only once for any given decl node. + + Second argument is the boundary that this field can be assumed to + be starting at (in bits). Zero means it can be assumed aligned + on any boundary that may be needed. */ + +extern void layout_decl PROTO((tree, unsigned)); + +/* Return an expr equal to X but certainly not valid as an lvalue. */ + +extern tree non_lvalue PROTO((tree)); +extern tree pedantic_non_lvalue PROTO((tree)); + +extern tree convert PROTO((tree, tree)); +extern tree size_in_bytes PROTO((tree)); +extern int int_size_in_bytes PROTO((tree)); +extern tree size_binop PROTO((enum tree_code, tree, tree)); +extern tree size_int PROTO((unsigned)); +extern tree round_up PROTO((tree, int)); +extern tree get_pending_sizes PROTO((void)); + +/* Type for sizes of data-type. */ + +extern tree sizetype; + +/* Concatenate two lists (chains of TREE_LIST nodes) X and Y + by making the last node in X point to Y. + Returns X, except if X is 0 returns Y. */ + +extern tree chainon PROTO((tree, tree)); + +/* Make a new TREE_LIST node from specified PURPOSE, VALUE and CHAIN. */ + +extern tree tree_cons PROTO((tree, tree, tree)); +extern tree perm_tree_cons PROTO((tree, tree, tree)); +extern tree temp_tree_cons PROTO((tree, tree, tree)); +extern tree saveable_tree_cons PROTO((tree, tree, tree)); +extern tree decl_tree_cons PROTO((tree, tree, tree)); + +/* Return the last tree node in a chain. */ + +extern tree tree_last PROTO((tree)); + +/* Reverse the order of elements in a chain, and return the new head. */ + +extern tree nreverse PROTO((tree)); + +/* Returns the length of a chain of nodes + (number of chain pointers to follow before reaching a null pointer). */ + +extern int list_length PROTO((tree)); + +/* integer_zerop (tree x) is nonzero if X is an integer constant of value 0 */ + +extern int integer_zerop PROTO((tree)); + +/* integer_onep (tree x) is nonzero if X is an integer constant of value 1 */ + +extern int integer_onep PROTO((tree)); + +/* integer_all_onesp (tree x) is nonzero if X is an integer constant + all of whose significant bits are 1. */ + +extern int integer_all_onesp PROTO((tree)); + +/* integer_pow2p (tree x) is nonzero is X is an integer constant with + exactly one bit 1. */ + +extern int integer_pow2p PROTO((tree)); + +/* staticp (tree x) is nonzero if X is a reference to data allocated + at a fixed address in memory. */ + +extern int staticp PROTO((tree)); + +/* Gets an error if argument X is not an lvalue. + Also returns 1 if X is an lvalue, 0 if not. */ + +extern int lvalue_or_else PROTO((tree, char *)); + +/* save_expr (EXP) returns an expression equivalent to EXP + but it can be used multiple times within context CTX + and only evaluate EXP once. */ + +extern tree save_expr PROTO((tree)); + +/* Return 1 if EXP contains a PLACEHOLDER_EXPR; i.e., if it represents a size + or offset that depends on a field within a record. + + Note that we only allow such expressions within simple arithmetic + or a COND_EXPR. */ + +extern int contains_placeholder_p PROTO((tree)); + +/* Given a tree EXP, a FIELD_DECL F, and a replacement value R, + return a tree with all occurrences of references to F in a + PLACEHOLDER_EXPR replaced by R. Note that we assume here that EXP + contains only arithmetic expressions. */ + +extern tree substitute_in_expr PROTO((tree, tree, tree)); + +/* Given a type T, a FIELD_DECL F, and a replacement value R, + return a new type with all size expressions that contain F + updated by replacing the reference to F with R. */ + +extern tree substitute_in_type PROTO((tree, tree, tree)); + +/* variable_size (EXP) is like save_expr (EXP) except that it + is for the special case of something that is part of a + variable size for a data type. It makes special arrangements + to compute the value at the right time when the data type + belongs to a function parameter. */ + +extern tree variable_size PROTO((tree)); + +/* stabilize_reference (EXP) returns an reference equivalent to EXP + but it can be used multiple times + and only evaluate the subexpressions once. */ + +extern tree stabilize_reference PROTO((tree)); + +/* Return EXP, stripped of any conversions to wider types + in such a way that the result of converting to type FOR_TYPE + is the same as if EXP were converted to FOR_TYPE. + If FOR_TYPE is 0, it signifies EXP's type. */ + +extern tree get_unwidened PROTO((tree, tree)); + +/* Return OP or a simpler expression for a narrower value + which can be sign-extended or zero-extended to give back OP. + Store in *UNSIGNEDP_PTR either 1 if the value should be zero-extended + or 0 if the value should be sign-extended. */ + +extern tree get_narrower PROTO((tree, int *)); + +/* Given MODE and UNSIGNEDP, return a suitable type-tree + with that mode. + The definition of this resides in language-specific code + as the repertoire of available types may vary. */ + +extern tree type_for_mode PROTO((enum machine_mode, int)); + +/* Given PRECISION and UNSIGNEDP, return a suitable type-tree + for an integer type with at least that precision. + The definition of this resides in language-specific code + as the repertoire of available types may vary. */ + +extern tree type_for_size PROTO((unsigned, int)); + +/* Given an integer type T, return a type like T but unsigned. + If T is unsigned, the value is T. + The definition of this resides in language-specific code + as the repertoire of available types may vary. */ + +extern tree unsigned_type PROTO((tree)); + +/* Given an integer type T, return a type like T but signed. + If T is signed, the value is T. + The definition of this resides in language-specific code + as the repertoire of available types may vary. */ + +extern tree signed_type PROTO((tree)); + +/* This function must be defined in the language-specific files. + expand_expr calls it to build the cleanup-expression for a TARGET_EXPR. + This is defined in a language-specific file. */ + +extern tree maybe_build_cleanup PROTO((tree)); + +/* Given an expression EXP that may be a COMPONENT_REF or an ARRAY_REF, + look for nested component-refs or array-refs at constant positions + and find the ultimate containing object, which is returned. */ + +extern tree get_inner_reference PROTO((tree, int *, int *, tree *, enum machine_mode *, int *, int *)); + +/* Return the FUNCTION_DECL which provides this _DECL with its context, + or zero if none. */ +extern tree decl_function_context PROTO((tree)); + +/* Return the RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE which provides + this _DECL with its context, or zero if none. */ +extern tree decl_type_context PROTO((tree)); + +/* Given the FUNCTION_DECL for the current function, + return zero if it is ok for this function to be inline. + Otherwise return a warning message with a single %s + for the function's name. */ + +extern char *function_cannot_inline_p PROTO((tree)); + +/* Return 1 if EXPR is the real constant zero. */ +extern int real_zerop PROTO((tree)); + +/* Declare commonly used variables for tree structure. */ + +/* An integer constant with value 0 */ +extern tree integer_zero_node; + +/* An integer constant with value 1 */ +extern tree integer_one_node; + +/* An integer constant with value 0 whose type is sizetype. */ +extern tree size_zero_node; + +/* An integer constant with value 1 whose type is sizetype. */ +extern tree size_one_node; + +/* A constant of type pointer-to-int and value 0 */ +extern tree null_pointer_node; + +/* A node of type ERROR_MARK. */ +extern tree error_mark_node; + +/* The type node for the void type. */ +extern tree void_type_node; + +/* The type node for the ordinary (signed) integer type. */ +extern tree integer_type_node; + +/* The type node for the unsigned integer type. */ +extern tree unsigned_type_node; + +/* The type node for the ordinary character type. */ +extern tree char_type_node; + +/* Points to the name of the input file from which the current input + being parsed originally came (before it went into cpp). */ +extern char *input_filename; + +/* Current line number in input file. */ +extern int lineno; + +/* Nonzero for -pedantic switch: warn about anything + that standard C forbids. */ +extern int pedantic; + +/* Nonzero means can safely call expand_expr now; + otherwise layout_type puts variable sizes onto `pending_sizes' instead. */ + +extern int immediate_size_expand; + +/* Points to the FUNCTION_DECL of the function whose body we are reading. */ + +extern tree current_function_decl; + +/* Nonzero if function being compiled can call setjmp. */ + +extern int current_function_calls_setjmp; + +/* Nonzero if function being compiled can call longjmp. */ + +extern int current_function_calls_longjmp; + +/* Nonzero means all ..._TYPE nodes should be allocated permanently. */ + +extern int all_types_permanent; + +/* Pointer to function to compute the name to use to print a declaration. */ + +extern char *(*decl_printable_name) (); + +/* Pointer to function to finish handling an incomplete decl at the + end of compilation. */ + +extern void (*incomplete_decl_finalize_hook) (); + +/* In tree.c */ +extern char *perm_calloc PROTO((int, long)); + +/* In stmt.c */ + +extern void expand_fixups PROTO((struct rtx_def *)); +extern tree expand_start_stmt_expr PROTO((void)); +extern tree expand_end_stmt_expr PROTO((tree)); +extern void expand_expr_stmt PROTO((tree)); +extern void expand_decl_init PROTO((tree)); +extern void clear_last_expr PROTO((void)); +extern void expand_label PROTO((tree)); +extern void expand_goto PROTO((tree)); +extern void expand_asm PROTO((tree)); +extern void expand_start_cond PROTO((tree, int)); +extern void expand_end_cond PROTO((void)); +extern void expand_start_else PROTO((void)); +extern void expand_start_elseif PROTO((tree)); +extern struct nesting *expand_start_loop PROTO((int)); +extern struct nesting *expand_start_loop_continue_elsewhere PROTO((int)); +extern void expand_loop_continue_here PROTO((void)); +extern void expand_end_loop PROTO((void)); +extern int expand_continue_loop PROTO((struct nesting *)); +extern int expand_exit_loop PROTO((struct nesting *)); +extern int expand_exit_loop_if_false PROTO((struct nesting *, + tree)); +extern int expand_exit_something PROTO((void)); + +extern void expand_null_return PROTO((void)); +extern void expand_return PROTO((tree)); +extern void expand_start_bindings PROTO((int)); +extern void expand_end_bindings PROTO((tree, int, int)); +extern tree last_cleanup_this_contour PROTO((void)); +extern void expand_start_case PROTO((int, tree, tree, + char *)); +extern void expand_end_case PROTO((tree)); +extern int pushcase PROTO((tree, + tree (*) (tree, tree), + tree, tree *)); +extern int pushcase_range PROTO((tree, tree, + tree (*) (tree, tree), + tree, tree *)); + +/* In fold-const.c */ + +/* Fold constants as much as possible in an expression. + Returns the simplified expression. + Acts only on the top level of the expression; + if the argument itself cannot be simplified, its + subexpressions are not changed. */ + +extern tree fold PROTO((tree)); + +extern int force_fit_type PROTO((tree, int)); +extern int add_double PROTO((HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT *, HOST_WIDE_INT *)); +extern int neg_double PROTO((HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT *, HOST_WIDE_INT *)); +extern int mul_double PROTO((HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT *, HOST_WIDE_INT *)); +extern void lshift_double PROTO((HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT, int, HOST_WIDE_INT *, + HOST_WIDE_INT *, int)); +extern void rshift_double PROTO((HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT, int, + HOST_WIDE_INT *, HOST_WIDE_INT *, int)); +extern void lrotate_double PROTO((HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT, int, HOST_WIDE_INT *, + HOST_WIDE_INT *)); +extern void rrotate_double PROTO((HOST_WIDE_INT, HOST_WIDE_INT, + HOST_WIDE_INT, int, HOST_WIDE_INT *, + HOST_WIDE_INT *)); +extern int operand_equal_p PROTO((tree, tree, int)); +extern tree invert_truthvalue PROTO((tree)); + +/* The language front-end must define these functions. */ + +/* Function of no arguments for initializing lexical scanning. */ +extern void init_lex PROTO((void)); +/* Function of no arguments for initializing the symbol table. */ +extern void init_decl_processing PROTO((void)); + +/* Functions called with no arguments at the beginning and end or processing + the input source file. */ +extern void lang_init PROTO((void)); +extern void lang_finish PROTO((void)); + +/* Funtion to identify which front-end produced the output file. */ +extern char *lang_identify PROTO((void)); + +/* Function to replace the DECL_LANG_SPECIFIC field of a DECL with a copy. */ +extern void copy_lang_decl PROTO((tree)); + +/* Function called with no arguments to parse and compile the input. */ +extern int yyparse PROTO((void)); +/* Function called with option as argument + to decode options starting with -f or -W or +. + It should return nonzero if it handles the option. */ +extern int lang_decode_option PROTO((char *)); + +/* Functions for processing symbol declarations. */ +/* Function to enter a new lexical scope. + Takes one argument: always zero when called from outside the front end. */ +extern void pushlevel PROTO((int)); +/* Function to exit a lexical scope. It returns a BINDING for that scope. + Takes three arguments: + KEEP -- nonzero if there were declarations in this scope. + REVERSE -- reverse the order of decls before returning them. + FUNCTIONBODY -- nonzero if this level is the body of a function. */ +extern tree poplevel PROTO((int, int, int)); +/* Set the BLOCK node for the current scope level. */ +extern void set_block PROTO((tree)); +/* Function to add a decl to the current scope level. + Takes one argument, a decl to add. + Returns that decl, or, if the same symbol is already declared, may + return a different decl for that name. */ +extern tree pushdecl PROTO((tree)); +/* Function to return the chain of decls so far in the current scope level. */ +extern tree getdecls PROTO((void)); +/* Function to return the chain of structure tags in the current scope level. */ +extern tree gettags PROTO((void)); + +extern tree build_range_type PROTO((tree, tree, tree)); + +/* Call when starting to parse a declaration: + make expressions in the declaration last the length of the function. + Returns an argument that should be passed to resume_momentary later. */ +extern int suspend_momentary PROTO((void)); + +extern int allocation_temporary_p PROTO((void)); + +/* Call when finished parsing a declaration: + restore the treatment of node-allocation that was + in effect before the suspension. + YES should be the value previously returned by suspend_momentary. */ +extern void resume_momentary PROTO((int)); + +/* Called after finishing a record, union or enumeral type. */ +extern void rest_of_type_compilation PROTO((tree, int)); + +/* Save the current set of obstacks, but don't change them. */ +extern void push_obstacks_nochange PROTO((void)); + +extern void permanent_allocation PROTO((int)); + +extern void push_momentary PROTO((void)); + +extern void clear_momentary PROTO((void)); + +extern void pop_momentary PROTO((void)); + +extern void end_temporary_allocation PROTO((void)); + +/* Pop the obstack selection stack. */ +extern void pop_obstacks PROTO((void)); diff --git a/gnu/usr.bin/cc/include/typeclass.h b/gnu/usr.bin/cc/include/typeclass.h new file mode 100644 index 0000000..b166042 --- /dev/null +++ b/gnu/usr.bin/cc/include/typeclass.h @@ -0,0 +1,14 @@ +/* Values returned by __builtin_classify_type. */ + +enum type_class +{ + no_type_class = -1, + void_type_class, integer_type_class, char_type_class, + enumeral_type_class, boolean_type_class, + pointer_type_class, reference_type_class, offset_type_class, + real_type_class, complex_type_class, + function_type_class, method_type_class, + record_type_class, union_type_class, + array_type_class, string_type_class, set_type_class, file_type_class, + lang_type_class +}; |