aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2000-11-25 00:43:32 +0000
committerNick Clifton <nickc@gcc.gnu.org>2000-11-25 00:43:32 +0000
commitc3edd394bb8b06993f89fd2ea1b0e112a501011b (patch)
tree97b5bb36bfa627b71d12b3bd70d0231be076ce0e /gcc
parentaac69a49c996b35d3dca614d8cf880611423014b (diff)
downloadgcc-c3edd394bb8b06993f89fd2ea1b0e112a501011b.zip
gcc-c3edd394bb8b06993f89fd2ea1b0e112a501011b.tar.gz
gcc-c3edd394bb8b06993f89fd2ea1b0e112a501011b.tar.bz2
Use target specific, language specific object files feature to allow build
v850 pragma support into gcc and gxx. From-SVN: r37727
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog30
-rw-r--r--gcc/config.gcc4
-rw-r--r--gcc/config/v850/t-v8505
-rw-r--r--gcc/config/v850/v850-c.c276
-rw-r--r--gcc/config/v850/v850.c255
-rw-r--r--gcc/config/v850/v850.h18
6 files changed, 345 insertions, 243 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4b1e113..b91468a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,35 @@
2000-11-24 Nick Clifton <nickc@redhat.com>
+ * config.gcc (v850-*-*): Define c_target_objs and
+ cxx_target_objs.
+
+ * config/v850/t-v850: Define how to build v850-c.o
+
+ * config/v850/v850.h (struct data_area_stack_element): Move
+ definition here from v850.c.
+
+ * config/v850v850.c: Include gcc.h to avoid compile time
+ warning.
+ (push_data_area): Move to v850-c.c.
+ (pop_data_area): Move to v850-c.c.
+ (mark_current_function_as_interrupt): Move to v850-c.c.
+ (GHS_default_section_names): Allow to be exported.
+ (GHS_current_section_names): Allow to be exported.
+ (data_area_stack_elements): Allow to be exported.
+ (ghs_pragma_section): Move to v850-c.c.
+ (ghs_pragma_interrupt): Move to v850-c.c.
+ (ghs_pragma_starttda): Move to v850-c.c.
+ (ghs_pragma_startsda): Move to v850-c.c.
+ (ghs_pragma_startzda): Move to v850-c.c.
+ (ghs_pragma_endtda): Move to v850-c.c.
+ (ghs_pragma_endsda): Move to v850-c.c.
+ (ghs_pragma_endzda): Move to v850-c.c.
+
+ * config/v850/v850-c.c: New file: Contains v850 specific
+ pragma parsing functions.
+
+2000-11-24 Nick Clifton <nickc@redhat.com>
+
* config.gcc (extra_objs): Remove duplicate description.
(c_target_objs): New variable. Contains target specific
object files for the gcc C compiler only.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index b2dbe00..9f25880 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3133,6 +3133,8 @@ v850-*-rtems*)
tm_file="${tm_file} dbx.h"
fi
use_collect2=no
+ c_target_objs="v850-c.o"
+ cxx_target_objs="v850-c.o"
;;
v850-*-*)
target_cpu_default="TARGET_CPU_generic"
@@ -3145,6 +3147,8 @@ v850-*-*)
tm_file="${tm_file} dbx.h"
fi
use_collect2=no
+ c_target_objs="v850-c.o"
+ cxx_target_objs="v850-c.o"
;;
vax-*-bsd*) # vaxen running BSD
use_collect2=yes
diff --git a/gcc/config/v850/t-v850 b/gcc/config/v850/t-v850
index 290d28b..479a235 100644
--- a/gcc/config/v850/t-v850
+++ b/gcc/config/v850/t-v850
@@ -31,7 +31,6 @@ LIB1ASMFUNCS = _mulsi3 \
_save_varargs \
_save_interrupt \
_save_all_interrupt
-
# We want fine grained libraries, so use the new code to build the
# floating point emulation libraries.
@@ -52,3 +51,7 @@ fp-bit.c: $(srcdir)/config/fp-bit.c
cat $(srcdir)/config/fp-bit.c >> fp-bit.c
TCFLAGS = -Wa,-mwarn-signed-overflow -Wa,-mwarn-unsigned-overflow
+
+v850-c.o: $(srcdir)/config/v850/v850-c.c
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+
diff --git a/gcc/config/v850/v850-c.c b/gcc/config/v850/v850-c.c
new file mode 100644
index 0000000..d541a66
--- /dev/null
+++ b/gcc/config/v850/v850-c.c
@@ -0,0 +1,276 @@
+/* v850 specific, C compiler specific functions.
+ Copyright (C) 2000 Free Software Foundation, Inc.
+ Contributed by Jeff Law (law@cygnus.com).
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "tree.h"
+#include "c-pragma.h"
+#include "c-lex.h"
+#include "toplev.h"
+#include "ggc.h"
+#include "tm_p.h"
+
+#ifndef streq
+#define streq(a,b) (strcmp (a, b) == 0)
+#endif
+
+static int pop_data_area PARAMS ((v850_data_area));
+static int push_data_area PARAMS ((v850_data_area));
+static int mark_current_function_as_interrupt PARAMS ((void));
+
+/* Push a data area onto the stack. */
+
+static int
+push_data_area (data_area)
+ v850_data_area data_area;
+{
+ data_area_stack_element * elem;
+
+ elem = (data_area_stack_element *) xmalloc (sizeof (* elem));
+
+ if (elem == NULL)
+ return 0;
+
+ elem->prev = data_area_stack;
+ elem->data_area = data_area;
+
+ data_area_stack = elem;
+
+ return 1;
+}
+
+/* Remove a data area from the stack. */
+
+static int
+pop_data_area (data_area)
+ v850_data_area data_area;
+{
+ if (data_area_stack == NULL)
+ warning ("#pragma GHS endXXXX found without previous startXXX");
+ else if (data_area != data_area_stack->data_area)
+ warning ("#pragma GHS endXXX does not match previous startXXX");
+ else
+ {
+ data_area_stack_element * elem;
+
+ elem = data_area_stack;
+ data_area_stack = data_area_stack->prev;
+
+ free (elem);
+
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Set the machine specific 'interrupt' attribute on the current function. */
+
+static int
+mark_current_function_as_interrupt ()
+{
+ tree name;
+
+ if (current_function_decl == NULL_TREE)
+ {
+ warning ("Cannot set interrupt attribute: no current function");
+ return 0;
+ }
+
+ name = get_identifier ("interrupt");
+
+ if (name == NULL_TREE || TREE_CODE (name) != IDENTIFIER_NODE)
+ {
+ warning ("Cannot set interrupt attribute: no such identifier");
+ return 0;
+ }
+
+ return valid_machine_attribute
+ (name, NULL_TREE, current_function_decl, NULL_TREE);
+}
+
+
+/* Support for GHS pragmata. */
+
+void
+ghs_pragma_section (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ int repeat;
+
+ /* #pragma ghs section [name = alias [, name = alias [, ...]]] */
+ do
+ {
+ tree x;
+ enum cpp_ttype type;
+ const char *sect, *alias;
+ enum GHS_section_kind kind;
+
+ type = c_lex (&x);
+
+ if (type == CPP_EOF && !repeat)
+ goto reset;
+ else if (type == CPP_NAME)
+ sect = IDENTIFIER_POINTER (x);
+ else
+ goto bad;
+ repeat = 0;
+
+ if (c_lex (&x) != CPP_EQ)
+ goto bad;
+ if (c_lex (&x) != CPP_NAME)
+ goto bad;
+
+ alias = IDENTIFIER_POINTER (x);
+
+ type = c_lex (&x);
+ if (type == CPP_COMMA)
+ repeat = 1;
+ else if (type != CPP_EOF)
+ warning ("junk at end of #pragma ghs section");
+
+ if (streq (sect, "data")) kind = GHS_SECTION_KIND_DATA;
+ else if (streq (sect, "text")) kind = GHS_SECTION_KIND_TEXT;
+ else if (streq (sect, "rodata")) kind = GHS_SECTION_KIND_RODATA;
+ else if (streq (sect, "const")) kind = GHS_SECTION_KIND_RODATA;
+ else if (streq (sect, "rosdata")) kind = GHS_SECTION_KIND_ROSDATA;
+ else if (streq (sect, "rozdata")) kind = GHS_SECTION_KIND_ROZDATA;
+ else if (streq (sect, "sdata")) kind = GHS_SECTION_KIND_SDATA;
+ else if (streq (sect, "tdata")) kind = GHS_SECTION_KIND_TDATA;
+ else if (streq (sect, "zdata")) kind = GHS_SECTION_KIND_ZDATA;
+ /* According to GHS beta documentation, the following should not be
+ allowed! */
+ else if (streq (sect, "bss")) kind = GHS_SECTION_KIND_BSS;
+ else if (streq (sect, "zbss")) kind = GHS_SECTION_KIND_ZDATA;
+ else
+ {
+ warning ("unrecognised section name \"%s\"", sect);
+ return;
+ }
+
+ if (streq (alias, "default"))
+ GHS_current_section_names [kind] = NULL;
+ else
+ GHS_current_section_names [kind] =
+ build_string (strlen (alias) + 1, alias);
+ }
+ while (repeat);
+
+ return;
+
+ bad:
+ warning ("malformed #pragma ghs section");
+ return;
+
+ reset:
+ /* #pragma ghs section \n: Reset all section names back to their defaults. */
+ {
+ int i;
+
+ for (i = COUNT_OF_GHS_SECTION_KINDS; i--;)
+ GHS_current_section_names [i] = NULL;
+ }
+}
+
+void
+ghs_pragma_interrupt (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ tree x;
+
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of #pragma ghs interrupt");
+
+ mark_current_function_as_interrupt ();
+}
+
+void
+ghs_pragma_starttda (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ tree x;
+
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of #pragma ghs starttda");
+
+ push_data_area (DATA_AREA_TDA);
+}
+
+void
+ghs_pragma_startsda (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ tree x;
+
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of #pragma ghs startsda");
+
+ push_data_area (DATA_AREA_SDA);
+}
+
+void
+ghs_pragma_startzda (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ tree x;
+
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of #pragma ghs startzda");
+
+ push_data_area (DATA_AREA_ZDA);
+}
+
+void
+ghs_pragma_endtda (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ tree x;
+
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of #pragma ghs endtda");
+
+ pop_data_area (DATA_AREA_TDA);
+}
+
+void
+ghs_pragma_endsda (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ tree x;
+
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of #pragma ghs endsda");
+
+ pop_data_area (DATA_AREA_SDA);
+}
+
+void
+ghs_pragma_endzda (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ tree x;
+
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of #pragma ghs endzda");
+
+ pop_data_area (DATA_AREA_ZDA);
+}
diff --git a/gcc/config/v850/v850.c b/gcc/config/v850/v850.c
index 5304e6e..8fd1602 100644
--- a/gcc/config/v850/v850.c
+++ b/gcc/config/v850/v850.c
@@ -38,7 +38,7 @@ Boston, MA 02111-1307, USA. */
#include "toplev.h"
#include "cpplib.h"
#include "c-lex.h"
-#include "c-pragma.h"
+#include "ggc.h"
#include "tm_p.h"
#ifndef streq
@@ -50,10 +50,7 @@ static void const_double_split
PARAMS ((rtx, HOST_WIDE_INT *, HOST_WIDE_INT *));
static int const_costs_int PARAMS ((HOST_WIDE_INT, int));
static void substitute_ep_register PARAMS ((rtx, rtx, int, int, rtx *, rtx *));
-static int push_data_area PARAMS ((v850_data_area));
-static int pop_data_area PARAMS ((v850_data_area));
static int ep_memory_offset PARAMS ((enum machine_mode, int));
-static int mark_current_function_as_interrupt PARAMS ((void));
static void v850_set_data_area PARAMS ((tree, v850_data_area));
/* True if the current function has anonymous arguments. */
@@ -68,8 +65,16 @@ struct small_memory_info small_memory[ (int)SMALL_MEMORY_max ] =
{ "zda", (char *)0, 0, 32768 },
};
+/* Names of the various data areas used on the v850. */
+tree GHS_default_section_names [(int) COUNT_OF_GHS_SECTION_KINDS];
+tree GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_KINDS];
+
+/* Track the current data area set by the data area pragma (which
+ can be nested). Tested by check_default_data_area. */
+data_area_stack_element * data_area_stack = NULL;
+
/* True if we don't need to check any more if the current
- function is an interrupt handler */
+ function is an interrupt handler. */
static int v850_interrupt_cache_p = FALSE;
/* Whether current function is an interrupt handler. */
@@ -1028,7 +1033,7 @@ not_power_of_two_operand (op, mode)
else if (mode == HImode)
mask = 0xffff;
else if (mode == SImode)
- mask = 0xffffffff;
+ mask = 0xffffffffU;
else
return 0;
@@ -1104,12 +1109,12 @@ Saved %d bytes (%d uses of register %s) in function %s, starting as insn %d, end
{
rtx addr = XEXP (*p_mem, 0);
- if (GET_CODE (addr) == REG && REGNO (addr) == regno)
+ if (GET_CODE (addr) == REG && REGNO (addr) == (unsigned) regno)
*p_mem = change_address (*p_mem, VOIDmode, *p_ep);
else if (GET_CODE (addr) == PLUS
&& GET_CODE (XEXP (addr, 0)) == REG
- && REGNO (XEXP (addr, 0)) == regno
+ && REGNO (XEXP (addr, 0)) == (unsigned) regno
&& GET_CODE (XEXP (addr, 1)) == CONST_INT
&& ((INTVAL (XEXP (addr, 1)))
< ep_memory_offset (GET_MODE (*p_mem),
@@ -2638,240 +2643,6 @@ v850_output_local (file, decl, name, size, align)
ASM_OUTPUT_ALIGNED_DECL_COMMON (file, decl, name, size, align);
}
-/* The following code is for handling pragmas supported by the
- v850 compiler produced by Green Hills Software. This is at
- the specific request of a customer. */
-
-/* Track the current data area set by the data area pragma (which
- can be nested). Tested by check_default_data_area. */
-
-typedef struct data_area_stack_element
-{
- struct data_area_stack_element * prev;
- v850_data_area data_area; /* current default data area. */
-} data_area_stack_element;
-
-static data_area_stack_element * data_area_stack = NULL;
-
-/* Names of the various data areas used on the v850. */
-static tree GHS_default_section_names [(int) COUNT_OF_GHS_SECTION_KINDS];
-static tree GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_KINDS];
-
-/* Push a data area onto the stack. */
-static int
-push_data_area (data_area)
- v850_data_area data_area;
-{
- data_area_stack_element * elem;
-
- elem = (data_area_stack_element *) xmalloc (sizeof (* elem));
-
- if (elem == NULL)
- return 0;
-
- elem->prev = data_area_stack;
- elem->data_area = data_area;
-
- data_area_stack = elem;
-
- return 1;
-}
-
-/* Remove a data area from the stack. */
-static int
-pop_data_area (data_area)
- v850_data_area data_area;
-{
- if (data_area_stack == NULL)
- warning ("#pragma GHS endXXXX found without previous startXXX");
- else if (data_area != data_area_stack->data_area)
- warning ("#pragma GHS endXXX does not match previous startXXX");
- else
- {
- data_area_stack_element * elem;
-
- elem = data_area_stack;
- data_area_stack = data_area_stack->prev;
-
- free (elem);
-
- return 1;
- }
-
- return 0;
-}
-
-/* Set the machine specific 'interrupt' attribute on the current function. */
-static int
-mark_current_function_as_interrupt ()
-{
- tree name;
-
- if (current_function_decl == NULL_TREE)
- {
- warning ("Cannot set interrupt attribute: no current function");
- return 0;
- }
-
- name = get_identifier ("interrupt");
-
- if (name == NULL_TREE || TREE_CODE (name) != IDENTIFIER_NODE)
- {
- warning ("Cannot set interrupt attribute: no such identifier");
- return 0;
- }
-
- return valid_machine_attribute
- (name, NULL_TREE, current_function_decl, NULL_TREE);
-}
-
-/* Support for GHS pragmata. */
-
-void
-ghs_pragma_section (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-{
- int repeat;
-
- /* #pragma ghs section [name = alias [, name = alias [, ...]]] */
- do {
- tree x;
- enum cpp_ttype type;
- const char *sect, *alias;
- enum GHS_section_kind kind;
-
- type = c_lex (&x);
- if (type == CPP_EOF && !repeat)
- goto reset;
- else if (type == CPP_NAME)
- sect = IDENTIFIER_POINTER (x);
- else
- goto bad;
- repeat = 0;
-
- if (c_lex (&x) != CPP_EQ)
- goto bad;
- if (c_lex (&x) != CPP_NAME)
- goto bad;
- alias = IDENTIFIER_POINTER (x);
-
- type = c_lex (&x);
- if (type == CPP_COMMA)
- repeat = 1;
- else if (type != CPP_EOF)
- warning ("junk at end of #pragma ghs section");
-
- if (streq (sect, "data")) kind = GHS_SECTION_KIND_DATA;
- else if (streq (sect, "text")) kind = GHS_SECTION_KIND_TEXT;
- else if (streq (sect, "rodata")) kind = GHS_SECTION_KIND_RODATA;
- else if (streq (sect, "const")) kind = GHS_SECTION_KIND_RODATA;
- else if (streq (sect, "rosdata")) kind = GHS_SECTION_KIND_ROSDATA;
- else if (streq (sect, "rozdata")) kind = GHS_SECTION_KIND_ROZDATA;
- else if (streq (sect, "sdata")) kind = GHS_SECTION_KIND_SDATA;
- else if (streq (sect, "tdata")) kind = GHS_SECTION_KIND_TDATA;
- else if (streq (sect, "zdata")) kind = GHS_SECTION_KIND_ZDATA;
- /* According to GHS beta documentation, the following should not be
- allowed! */
- else if (streq (sect, "bss")) kind = GHS_SECTION_KIND_BSS;
- else if (streq (sect, "zbss")) kind = GHS_SECTION_KIND_ZDATA;
- else
- {
- warning ("unrecognised section name \"%s\"", sect);
- return;
- }
-
- if (streq (alias, "default"))
- GHS_current_section_names [kind] = NULL;
- else
- GHS_current_section_names [kind] =
- build_string (strlen (alias) + 1, alias);
-
- } while (repeat);
- return;
-
- bad:
- warning ("malformed #pragma ghs section");
- return;
-
- reset:
- /* #pragma ghs section \n: Reset all section names back to their defaults. */
- {
- int i;
- for (i = COUNT_OF_GHS_SECTION_KINDS; i--;)
- GHS_current_section_names [i] = NULL;
- }
-}
-
-void
-ghs_pragma_interrupt (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-{
- tree x;
- if (c_lex (&x) != CPP_EOF)
- warning ("junk at end of #pragma ghs interrupt");
- mark_current_function_as_interrupt ();
-}
-
-void
-ghs_pragma_starttda (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-{
- tree x;
- if (c_lex (&x) != CPP_EOF)
- warning ("junk at end of #pragma ghs starttda");
- push_data_area (DATA_AREA_TDA);
-}
-
-void
-ghs_pragma_startsda (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-{
- tree x;
- if (c_lex (&x) != CPP_EOF)
- warning ("junk at end of #pragma ghs startsda");
- push_data_area (DATA_AREA_SDA);
-}
-
-void
-ghs_pragma_startzda (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-{
- tree x;
- if (c_lex (&x) != CPP_EOF)
- warning ("junk at end of #pragma ghs startzda");
- push_data_area (DATA_AREA_ZDA);
-}
-
-void
-ghs_pragma_endtda (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-{
- tree x;
- if (c_lex (&x) != CPP_EOF)
- warning ("junk at end of #pragma ghs endtda");
- pop_data_area (DATA_AREA_TDA);
-}
-
-void
-ghs_pragma_endsda (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-{
- tree x;
- if (c_lex (&x) != CPP_EOF)
- warning ("junk at end of #pragma ghs endsda");
- pop_data_area (DATA_AREA_SDA);
-}
-
-void
-ghs_pragma_endzda (pfile)
- cpp_reader *pfile ATTRIBUTE_UNUSED;
-{
- tree x;
- if (c_lex (&x) != CPP_EOF)
- warning ("junk at end of #pragma ghs endzda");
- pop_data_area (DATA_AREA_ZDA);
-}
-
/* Add data area to the given declaration if a ghs data area pragma is
currently in effect (#pragma ghs startXXX/endXXX). */
void
diff --git a/gcc/config/v850/v850.h b/gcc/config/v850/v850.h
index eb41ff9..ccf4967 100644
--- a/gcc/config/v850/v850.h
+++ b/gcc/config/v850/v850.h
@@ -1555,6 +1555,24 @@ enum GHS_section_kind
COUNT_OF_GHS_SECTION_KINDS /* must be last */
};
+/* The following code is for handling pragmas supported by the
+ v850 compiler produced by Green Hills Software. This is at
+ the specific request of a customer. */
+
+typedef struct data_area_stack_element
+{
+ struct data_area_stack_element * prev;
+ v850_data_area data_area; /* Current default data area. */
+} data_area_stack_element;
+
+/* Track the current data area set by the
+ data area pragma (which can be nested). */
+extern data_area_stack_element * data_area_stack;
+
+/* Names of the various data areas used on the v850. */
+extern union tree_node * GHS_default_section_names [(int) COUNT_OF_GHS_SECTION_KINDS];
+extern union tree_node * GHS_current_section_names [(int) COUNT_OF_GHS_SECTION_KINDS];
+
/* The assembler op to start the file. */
#define FILE_ASM_OP "\t.file\n"