Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
b3865ca9
Commit
b3865ca9
authored
Mar 21, 1992
by
Richard Stallman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
*** empty log message ***
From-SVN: r551
parent
24f6f95e
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
199 additions
and
34 deletions
+199
-34
gcc/config/m68k/sun3.h
+8
-12
gcc/config/svr4.h
+19
-16
gcc/gcc.c
+172
-6
No files found.
gcc/config/m68k/sun3.h
View file @
b3865ca9
...
...
@@ -43,14 +43,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* -m68881 is the default */
#define CPP_SPEC \
"%{!msoft-float:%{mfpa:-D__HAVE_FPA__ }%{!mfpa:-D__HAVE_68881__ }}\
%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
#else
#if TARGET_DEFAULT & 0100
/* -mfpa is the default */
#define CPP_SPEC \
"%{!msoft-float:%{m68881:-D__HAVE_68881__ }%{!m68881:-D__HAVE_FPA__ }}\
%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}}} \
%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
#else
...
...
@@ -58,10 +51,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* -msoft-float is the default */
#define CPP_SPEC \
"%{m68881:-D__HAVE_68881__ }%{mfpa:-D__HAVE_FPA__ }\
%{m68000:-D__mc68010__}%{mc68000:-D__mc68010__}%{!mc68000:%{!m68000:-D__mc68020__}}} \
%{!ansi:%{m68000:-Dmc68010}%{mc68000:-Dmc68010}%{!mc68000:%{!m68000:-Dmc68020}}}"
#endif
#endif
/* Prevent error on `-sun3' and `-target sun3' options. */
...
...
@@ -81,7 +74,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define WORD_SWITCH_TAKES_ARG(STR) \
(!strcmp (STR, "Tdata") || !strcmp (STR, "include") \
|| !strcmp (STR, "imacros") || !strcmp (STR, "target") \
|| !strcmp (STR, "assert"))
|| !strcmp (STR, "assert")
|| !strcmp (STR, "aux-info")
)
/* -m68000 requires special flags to the assembler. */
...
...
@@ -167,6 +160,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Allow folding division by zero. */
#define REAL_INFINITY
/* Generate calls to memcpy, memcmp and memset. */
#define TARGET_MEM_FUNCTIONS
/* This is how to output an assembler line defining a `double' constant. */
#undef ASM_OUTPUT_DOUBLE
...
...
@@ -174,7 +170,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
{ \
if (REAL_VALUE_ISINF (VALUE)) \
fprintf (FILE, "\t.double 0r%s99e999\n", (VALUE) > 0 ? "" : "-"); \
else if (
isnan (VALUE))
\
else if (
REAL_VALUE_ISNAN (VALUE))
\
{ \
union { double d; long l[2];} t; \
t.d = (VALUE); \
...
...
@@ -191,7 +187,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
{ \
if (REAL_VALUE_ISINF (VALUE)) \
fprintf (FILE, "\t.single 0r%s99e999\n", (VALUE) > 0 ? "" : "-"); \
else if (
isnan (VALUE))
\
else if (
REAL_VALUE_ISNAN (VALUE))
\
{ \
union { float f; long l;} t; \
t.f = (VALUE); \
...
...
gcc/config/svr4.h
View file @
b3865ca9
...
...
@@ -72,7 +72,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
there are no such switches except those implemented by GCC itself. */
#define WORD_SWITCH_TAKES_ARG(STR) \
(!strcmp (STR, "include") || !strcmp (STR, "imacros"))
(!strcmp (STR, "include") || !strcmp (STR, "imacros") \
|| !strcmp (STR, "aux-info"))
/* You should redefine CPP_PREDEFINES in any file which includes this one.
The definition should be appropriate for the type of target system
...
...
@@ -249,6 +250,8 @@ do { \
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE BITS_PER_WORD
#define MULTIBYTE_CHARS
#undef ASM_BYTE_OP
#define ASM_BYTE_OP "\t.byte"
...
...
@@ -303,12 +306,12 @@ do { \
the linker seems to want the alignment of data objects
to depend on their types. We do exactly that here. */
#define BSS_ASM_OP "
\t
.bss"
#define BSS_ASM_OP ".bss"
#undef ASM_OUTPUT_ALIGNED_LOCAL
#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGN) \
do { \
fprintf ((FILE), "%s\t%s,%u,%u\n", \
fprintf ((FILE), "
\t
%s\t%s,%u,%u\n", \
BSS_ASM_OP, (NAME), (SIZE), (ALIGN) / BITS_PER_UNIT); \
} while (0)
...
...
@@ -316,7 +319,7 @@ do { \
specific value in some section. This is the same for all known svr4
assemblers. */
#define INT_ASM_OP "
\t.long\t
"
#define INT_ASM_OP "
.long
"
/* This is the pseudo-op used to generate a contiguous sequence of byte
values from a double-quoted string WITHOUT HAVING A TERMINATING NUL
...
...
@@ -335,9 +338,9 @@ do { \
#define USE_CONST_SECTION 1
#define CONST_SECTION_ASM_OP "
\t
.section\t.rodata"
#define CTORS_SECTION_ASM_OP "
\t.section\t.ctors,\"a\",@progbits\n
"
#define DTORS_SECTION_ASM_OP "
\t.section\t.dtors,\"a\",@progbits\n
"
#define CONST_SECTION_ASM_OP ".section\t.rodata"
#define CTORS_SECTION_ASM_OP "
.section\t.ctors,\"a\",@progbits
"
#define DTORS_SECTION_ASM_OP "
.section\t.dtors,\"a\",@progbits
"
/* On svr4, we *do* have support for the .init section, and we can put
stuff in there to be executed before `main'. We let crtstuff.c and
...
...
@@ -345,7 +348,7 @@ do { \
says how to change sections to the .init section. This is the same
for all know svr4 assemblers. */
#define INIT_SECTION_ASM_OP "
\t
.section\t.init"
#define INIT_SECTION_ASM_OP ".section\t.init"
/* A default list of other sections which we might be "in" at any given
time. For targets that use additional sections (e.g. .tdesc) you
...
...
@@ -409,7 +412,7 @@ dtors_section () \
#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
do { \
ctors_section (); \
fprintf (FILE, "%s\t ", INT_ASM_OP); \
fprintf (FILE, "
\t
%s\t ", INT_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
...
...
@@ -419,7 +422,7 @@ dtors_section () \
#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
do { \
dtors_section (); \
fprintf (FILE, "%s\t ", INT_ASM_OP); \
fprintf (FILE, "
\t
%s\t ", INT_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, "\n"); \
} while (0)
...
...
@@ -465,8 +468,8 @@ dtors_section () \
different pseudo-op names for these, they may be overridden in the
file which includes this one. */
#define TYPE_ASM_OP "
\t
.type"
#define SIZE_ASM_OP "
\t
.size"
#define TYPE_ASM_OP ".type"
#define SIZE_ASM_OP ".size"
/* The following macro defines the format used to output the second
operand of the .type assembler directive. Different svr4 assemblers
...
...
@@ -484,7 +487,7 @@ dtors_section () \
#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
do { \
fprintf (FILE, "%s\t ", TYPE_ASM_OP); \
fprintf (FILE, "
\t
%s\t ", TYPE_ASM_OP); \
assemble_name (FILE, NAME); \
putc (',', FILE); \
fprintf (FILE, TYPE_OPERAND_FMT, "function"); \
...
...
@@ -496,14 +499,14 @@ dtors_section () \
#define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL) \
do { \
fprintf (FILE, "%s\t ", TYPE_ASM_OP); \
fprintf (FILE, "
\t
%s\t ", TYPE_ASM_OP); \
assemble_name (FILE, NAME); \
putc (',', FILE); \
fprintf (FILE, TYPE_OPERAND_FMT, "object"); \
putc ('\n', FILE); \
if (!flag_inhibit_size_directive) \
{ \
fprintf (FILE, "%s\t ", SIZE_ASM_OP); \
fprintf (FILE, "
\t
%s\t ", SIZE_ASM_OP); \
assemble_name (FILE, NAME); \
fprintf (FILE, ",%d\n", int_size_in_bytes (TREE_TYPE (decl))); \
} \
...
...
@@ -521,7 +524,7 @@ dtors_section () \
labelno++; \
ASM_GENERATE_INTERNAL_LABEL (label, "Lfe", labelno); \
ASM_OUTPUT_INTERNAL_LABEL (FILE, "Lfe", labelno); \
fprintf (FILE, "%s\t ", SIZE_ASM_OP); \
fprintf (FILE, "
\t
%s\t ", SIZE_ASM_OP); \
assemble_name (FILE, (FNAME)); \
fprintf (FILE, ","); \
assemble_name (FILE, label); \
...
...
gcc/gcc.c
View file @
b3865ca9
...
...
@@ -124,6 +124,13 @@ static int cross_compile = 0;
static
struct
obstack
obstack
;
/* This is the obstack to build an environment variable to pass to
collect2 that describes all of the relavant switches of what to
pass the compiler in building the list of pointers to constructors
and destructors. */
static
struct
obstack
collect_obstack
;
extern
char
*
version_string
;
static
void
set_spec
();
...
...
@@ -237,6 +244,8 @@ or with constant text in a single argument.
%{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'.
%{.S:X} substitutes X, but only if processing a file with suffix S.
%{!.S:X} substitutes X, but only if NOT processing a file with suffix S.
%(Spec) processes a specification defined in a specs file as *Spec:
%[Spec] as above, but put __ around -D arguments
The conditional text X in a %{S:X} or %{!S:X} construct may contain
other nested % constructs or spaces, or even newlines. They are
...
...
@@ -352,7 +361,7 @@ static char *switches_need_spaces = SWITCHES_NEED_SPACES;
#ifndef WORD_SWITCH_TAKES_ARG
#define WORD_SWITCH_TAKES_ARG(STR) \
(!strcmp (STR, "Tdata") || !strcmp (STR, "include") \
|| !strcmp (STR, "imacros"))
|| !strcmp (STR, "imacros")
|| !strcmp (STR, "aux-info")
)
#endif
/* Record the mapping from file suffixes for compilation specs. */
...
...
@@ -399,6 +408,7 @@ static struct compiler default_compilers[] =
%{!Q:-quiet} -dumpbase %b.c %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
%{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
%{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |
\n
\
%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
...
...
@@ -431,6 +441,7 @@ static struct compiler default_compilers[] =
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \
%{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \
-lang-objc %{gen-decls} \
%{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |
\n
\
%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
...
...
@@ -465,6 +476,7 @@ static struct compiler default_compilers[] =
%{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
%{v:-version} %{pg:-p} %{p} %{f*}\
%{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |
\n
\
%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
...
...
@@ -475,6 +487,7 @@ static struct compiler default_compilers[] =
"cc1 %i %1 %{!Q:-quiet} %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
%{v:-version} %{pg:-p} %{p} %{f*}\
%{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |
\n
\
%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
...
...
@@ -484,6 +497,7 @@ static struct compiler default_compilers[] =
"cc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\
%{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} %{traditional}\
%{v:-version} %{pg:-p} %{p} %{f*}\
%{aux-info*}\
%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |
\n
\
%{!S:as %{R} %{j} %{J} %{h} %{d2} %a \
...
...
@@ -528,7 +542,7 @@ static char *link_command_spec = "\
/* Use -l and have the linker do the search. */
static
char
*
link_command_spec
=
"\
%{!c:%{!M:%{!MM:%{!E:%{!S:ld %X %l %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
%{r} %{T*} %{t} %{x} %{z}\
%{r} %{
s} %{
T*} %{t} %{x} %{z}\
%{!A:%{!nostdlib:%S}} \
%{L*} %D %o %{!nostdlib:-lgcc %L -lgcc %{!A:%E}}
\n
}}}}}"
;
#endif
...
...
@@ -620,7 +634,6 @@ read_specs (filename)
else
if
(
in
[
0
]
==
'#'
)
{
while
(
*
in
&&
*
in
!=
'\n'
)
in
++
;
if
(
*
in
)
in
++
;
}
else
*
out
++
=
*
in
++
;
...
...
@@ -678,7 +691,7 @@ skip_whitespace (p)
}
/* Structure to keep track of the specs that have been defined so far. These
are accessed using %
Sspecname
in a compiler or link spec. */
are accessed using %
(specname) or %[specname]
in a compiler or link spec. */
struct
spec_list
{
...
...
@@ -1046,6 +1059,103 @@ choose_temp_base ()
temp_filename_length
=
strlen
(
temp_filename
);
}
/* Routine to add variables to the environment. We do this to pass
the pathname of the gcc driver, and the directories search to the
collect2 program, which is being run as ld. This way, we can be
sure of executing the right compiler when collect2 wants to build
constructors and destructors. Since the environment variables we
use come from an obstack, we don't have to worry about allocating
space for them. */
#ifndef HAVE_PUTENV
putenv
(
str
)
char
*
str
;
{
#ifndef __MSDOS__
/* not sure about MS/DOS */
#ifndef VMS
/* nor about VMS */
extern
char
**
environ
;
char
**
old_environ
=
environ
;
char
**
envp
;
int
num_envs
=
0
;
int
name_len
=
1
;
int
str_len
=
strlen
(
str
);
char
*
p
=
str
;
int
ch
;
while
((
ch
=
*
p
++
)
!=
'\0'
&&
ch
!=
'='
)
name_len
++
;
if
(
!
ch
)
abort
();
/* Search for replacing an existing environment variable, and
count the number of total environment variables. */
for
(
envp
=
old_environ
;
*
envp
;
envp
++
)
{
num_envs
++
;
if
(
!
strncmp
(
str
,
*
envp
,
name_len
))
{
*
envp
=
str
;
return
;
}
}
/* Add a new environment variable */
environ
=
(
char
**
)
xmalloc
(
sizeof
(
char
*
)
*
(
num_envs
+
2
));
*
environ
=
str
;
bcopy
(
old_environ
,
environ
+
1
,
sizeof
(
char
*
)
*
(
num_envs
+
1
));
#endif
/* VMS */
#endif
/* __MSDOS__ */
}
#endif
/* HAVE_PUTENV */
/* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables for collect. */
static
void
putenv_from_prefixes
(
paths
,
env_var
)
struct
path_prefix
*
paths
;
char
*
env_var
;
{
int
suffix_len
=
(
machine_suffix
)
?
strlen
(
machine_suffix
)
:
0
;
int
first_time
=
TRUE
;
struct
prefix_list
*
pprefix
;
obstack_grow
(
&
collect_obstack
,
env_var
,
strlen
(
env_var
));
for
(
pprefix
=
paths
->
plist
;
pprefix
!=
0
;
pprefix
=
pprefix
->
next
)
{
int
len
=
strlen
(
pprefix
->
prefix
);
if
(
machine_suffix
)
{
if
(
!
first_time
)
obstack_grow
(
&
collect_obstack
,
":"
,
1
);
first_time
=
FALSE
;
obstack_grow
(
&
collect_obstack
,
pprefix
->
prefix
,
len
);
obstack_grow
(
&
collect_obstack
,
machine_suffix
,
suffix_len
);
}
if
(
!
pprefix
->
require_machine_suffix
)
{
if
(
!
first_time
)
obstack_grow
(
&
collect_obstack
,
":"
,
1
);
first_time
=
FALSE
;
obstack_grow
(
&
collect_obstack
,
pprefix
->
prefix
,
len
);
}
}
obstack_grow
(
&
collect_obstack
,
"
\0
"
,
1
);
putenv
(
obstack_finish
(
&
collect_obstack
));
}
/* Search for NAME using the prefix list PREFIXES. MODE is passed to
access to check permissions.
Return 0 if not found, otherwise return its name, allocated with malloc. */
...
...
@@ -1427,7 +1537,7 @@ execute ()
/* If -v, print what we are about to do, and maybe query. */
if
(
verbose_flag
||
save_temps_flag
)
if
(
verbose_flag
)
{
/* Print each piped command as a separate line. */
for
(
i
=
0
;
i
<
n_commands
;
i
++
)
...
...
@@ -2508,6 +2618,10 @@ do_spec_1 (spec, inswitch, soft_matched_part)
do_spec_1
(
buf
,
0
,
NULL
);
}
}
/* Discard the closing paren or bracket. */
if
(
*
p
)
p
++
;
}
break
;
...
...
@@ -2622,7 +2736,7 @@ handle_braces (p)
/* First see whether we have %*. */
substitution
=
0
;
while
(
*
r
&&
*
r
==
'}'
)
while
(
r
<
q
)
{
if
(
*
r
==
'%'
&&
r
[
1
]
==
'*'
)
substitution
=
1
;
...
...
@@ -2828,6 +2942,13 @@ main (argc, argv)
obstack_init
(
&
obstack
);
/* Set up to remember the pathname of gcc and any options
needed for collect. */
obstack_init
(
&
collect_obstack
);
obstack_grow
(
&
collect_obstack
,
"COLLECT_GCC="
,
sizeof
(
"COLLECT_GCC="
)
-
1
);
obstack_grow
(
&
collect_obstack
,
programname
,
strlen
(
programname
)
+
1
);
putenv
(
obstack_finish
(
&
collect_obstack
));
/* Choose directory for temp files. */
choose_temp_base
();
...
...
@@ -2983,6 +3104,40 @@ main (argc, argv)
if
(
error_count
==
0
)
{
int
tmp
=
execution_count
;
int
i
;
int
first_time
;
/* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
for collect. */
putenv_from_prefixes
(
&
exec_prefix
,
"COMPILER_PATH="
);
putenv_from_prefixes
(
&
startfile_prefix
,
"LIBRARY_PATH="
);
/* Build COLLECT_GCC_OPTIONS to have all of the options specified to
the compiler. */
obstack_grow
(
&
collect_obstack
,
"COLLECT_GCC_OPTIONS="
,
sizeof
(
"COLLECT_GCC_OPTIONS="
)
-
1
);
first_time
=
TRUE
;
for
(
i
=
0
;
i
<
n_switches
;
i
++
)
{
char
**
args
;
if
(
!
first_time
)
obstack_grow
(
&
collect_obstack
,
" "
,
1
);
first_time
=
FALSE
;
obstack_grow
(
&
collect_obstack
,
"-"
,
1
);
obstack_grow
(
&
collect_obstack
,
switches
[
i
].
part1
,
strlen
(
switches
[
i
].
part1
));
for
(
args
=
switches
[
i
].
args
;
args
&&
*
args
;
args
++
)
{
obstack_grow
(
&
collect_obstack
,
" "
,
1
);
obstack_grow
(
&
collect_obstack
,
*
args
,
strlen
(
*
args
));
}
}
obstack_grow
(
&
collect_obstack
,
"
\0
"
,
1
);
putenv
(
obstack_finish
(
&
collect_obstack
));
value
=
do_spec
(
link_command_spec
);
if
(
value
<
0
)
error_count
=
1
;
...
...
@@ -3236,6 +3391,7 @@ validate_all_switches ()
struct
compiler
*
comp
;
register
char
*
p
;
register
char
c
;
struct
spec_list
*
spec
;
for
(
comp
=
compilers
;
comp
->
spec
;
comp
++
)
{
...
...
@@ -3246,6 +3402,16 @@ validate_all_switches ()
validate_switches
(
p
+
1
);
}
/* look through the linked list of extra specs read from the specs file */
for
(
spec
=
specs
;
spec
;
spec
=
spec
->
next
)
{
p
=
spec
->
spec
;
while
(
c
=
*
p
++
)
if
(
c
==
'%'
&&
*
p
==
'{'
)
/* We have a switch spec. */
validate_switches
(
p
+
1
);
}
p
=
link_command_spec
;
while
(
c
=
*
p
++
)
if
(
c
==
'%'
&&
*
p
==
'{'
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment