This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
output # <srcline> between #APP and #NO_APP, for asm statements
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 03 Mar 2007 02:50:12 -0300
- Subject: output # <srcline> between #APP and #NO_APP, for asm statements
This patch arranges for us to emit # <line> "<source>" directives
within #APP/#NO_APP, such that errors in the assembly in asm
statements can be reported by the assembler using the source line
number.
A few gotchas:
- If the assembler doesn't recognize # <line>, this won't work. Since
it's comment, it shouldn't cause problems either.
- If the line breaks in the asm statement don't match line breaks in
the asm output, the line number won't quite match the precise
location of the error.
- There's no currently way to tell the assembler to return to whatever
logical line number it had before we switch to an "included" file.
I've adopted '# 0 "" 2' to convey this information, but current
assemblers don't implement this. As a result, if there's any error
in the assembly output emitted by the compiler, it will issue error
messages referring to the empty file name and a wrong line number.
It won't reject this line, though.
Tested on x86_64-linux-gnu. Ok to install?
for gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* rtl.def (ASM_INPUT): Add location.
* rtl.h (ASM_INPUT_SOURCE_LOCATION): New.
(ASM_INPUT_SOURCE_FILE, ASM_INPUT_SOURCE_LINE): New.
(decode_asm_operands): Add loc operand.
(gen_rtx_ASM_INPUT, gen_rtx_ASM_INPUT_loc): Define.
* stmt.c (expand_asm): Rename to...
(expand_asm_loc): ... this. Add locus argument. Pass it on to
gen_rtx_ASM_INPUT_loc.
(expand_asm_expr): Adjust.
* recog.c (decode_asm_operands): Add loc operand.
(check_asm_operands, extract_insn): Adjust.
* reload1.c (maybe_fix_stack_asms): Likewise.
* final.c (asm_insn_count): Likewise.
(final_scan_insn): Output # line before and after asm.
Index: gcc/final.c
===================================================================
--- gcc/final.c.orig 2006-12-26 03:00:56.000000000 -0200
+++ gcc/final.c 2007-02-28 03:56:01.000000000 -0300
@@ -1,6 +1,6 @@
/* Convert RTL to assembler code and output it, for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GCC.
@@ -1357,7 +1357,7 @@ asm_insn_count (rtx body)
if (GET_CODE (body) == ASM_INPUT)
template = XSTR (body, 0);
else
- template = decode_asm_operands (body, NULL, NULL, NULL, NULL);
+ template = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL);
for (; *template; template++)
if (IS_ASM_LOGICAL_LINE_SEPARATOR (*template) || *template == '\n')
@@ -2068,12 +2068,25 @@ final_scan_insn (rtx insn, FILE *file, i
if (string[0])
{
+ location_t loc;
+
if (! app_on)
{
fputs (ASM_APP_ON, file);
app_on = 1;
}
+#ifdef USE_MAPPED_LOCATION
+ loc = ASM_INPUT_SOURCE_LOCATION (body);
+#else
+ loc.file = ASM_INPUT_SOURCE_FILE (body);
+ loc.line = ASM_INPUT_SOURCE_LINE (body);
+#endif
+ if (loc.file && loc.line)
+ fprintf (asm_out_file, "%s %i \"%s\" 1\n",
+ ASM_COMMENT_START, loc.line, loc.file);
fprintf (asm_out_file, "\t%s\n", string);
+ if (loc.file && loc.line)
+ fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START);
}
break;
}
@@ -2084,12 +2097,13 @@ final_scan_insn (rtx insn, FILE *file, i
unsigned int noperands = asm_noperands (body);
rtx *ops = alloca (noperands * sizeof (rtx));
const char *string;
+ location_t loc;
/* There's no telling what that did to the condition codes. */
CC_STATUS_INIT;
/* Get out the operand values. */
- string = decode_asm_operands (body, ops, NULL, NULL, NULL);
+ string = decode_asm_operands (body, ops, NULL, NULL, NULL, &loc);
/* Inhibit dieing on what would otherwise be compiler bugs. */
insn_noperands = noperands;
this_is_asm_operands = insn;
@@ -2106,7 +2120,12 @@ final_scan_insn (rtx insn, FILE *file, i
fputs (ASM_APP_ON, file);
app_on = 1;
}
+ if (loc.file && loc.line)
+ fprintf (asm_out_file, "%s %i \"%s\" 1\n",
+ ASM_COMMENT_START, loc.line, loc.file);
output_asm_insn (string, ops);
+ if (loc.file && loc.line)
+ fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START);
}
this_is_asm_operands = 0;
Index: gcc/recog.c
===================================================================
--- gcc/recog.c.orig 2006-12-20 02:19:35.000000000 -0200
+++ gcc/recog.c 2007-02-28 03:47:11.000000000 -0300
@@ -1,6 +1,6 @@
/* Subroutines used by or related to instruction recognition.
Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
This file is part of GCC.
@@ -140,7 +140,7 @@ check_asm_operands (rtx x)
operands = alloca (noperands * sizeof (rtx));
constraints = alloca (noperands * sizeof (char *));
- decode_asm_operands (x, operands, NULL, constraints, NULL);
+ decode_asm_operands (x, operands, NULL, constraints, NULL, NULL);
for (i = 0; i < noperands; i++)
{
@@ -1492,15 +1492,16 @@ asm_noperands (rtx body)
const char *
decode_asm_operands (rtx body, rtx *operands, rtx **operand_locs,
- const char **constraints, enum machine_mode *modes)
+ const char **constraints, enum machine_mode *modes,
+ location_t *loc)
{
int i;
int noperands;
- const char *template = 0;
+ rtx asmop = 0;
if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
{
- rtx asmop = SET_SRC (body);
+ asmop = SET_SRC (body);
/* Single output operand: BODY is (set OUTPUT (asm_operands ....)). */
noperands = ASM_OPERANDS_INPUT_LENGTH (asmop) + 1;
@@ -1527,11 +1528,10 @@ decode_asm_operands (rtx body, rtx *oper
constraints[0] = ASM_OPERANDS_OUTPUT_CONSTRAINT (asmop);
if (modes)
modes[0] = GET_MODE (SET_DEST (body));
- template = ASM_OPERANDS_TEMPLATE (asmop);
}
else if (GET_CODE (body) == ASM_OPERANDS)
{
- rtx asmop = body;
+ asmop = body;
/* No output operands: BODY is (asm_operands ....). */
noperands = ASM_OPERANDS_INPUT_LENGTH (asmop);
@@ -1549,13 +1549,12 @@ decode_asm_operands (rtx body, rtx *oper
if (modes)
modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
}
- template = ASM_OPERANDS_TEMPLATE (asmop);
}
else if (GET_CODE (body) == PARALLEL
&& GET_CODE (XVECEXP (body, 0, 0)) == SET
&& GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
{
- rtx asmop = SET_SRC (XVECEXP (body, 0, 0));
+ asmop = SET_SRC (XVECEXP (body, 0, 0));
int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs. */
int nin = ASM_OPERANDS_INPUT_LENGTH (asmop);
int nout = 0; /* Does not include CLOBBERs. */
@@ -1591,15 +1590,13 @@ decode_asm_operands (rtx body, rtx *oper
if (modes)
modes[i + nout] = ASM_OPERANDS_INPUT_MODE (asmop, i);
}
-
- template = ASM_OPERANDS_TEMPLATE (asmop);
}
else if (GET_CODE (body) == PARALLEL
&& GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
{
/* No outputs, but some CLOBBERs. */
- rtx asmop = XVECEXP (body, 0, 0);
+ asmop = XVECEXP (body, 0, 0);
int nin = ASM_OPERANDS_INPUT_LENGTH (asmop);
for (i = 0; i < nin; i++)
@@ -1614,10 +1611,19 @@ decode_asm_operands (rtx body, rtx *oper
modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
}
- template = ASM_OPERANDS_TEMPLATE (asmop);
}
- return template;
+ if (loc)
+ {
+#ifdef USE_MAPPED_LOCATION
+ *loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
+#else
+ loc->file = ASM_OPERANDS_SOURCE_FILE (asmop);
+ loc->line = ASM_OPERANDS_SOURCE_LINE (asmop);
+#endif
+ }
+
+ return ASM_OPERANDS_TEMPLATE (asmop);
}
/* Check if an asm_operand matches its constraints.
@@ -2086,7 +2092,7 @@ extract_insn (rtx insn)
decode_asm_operands (body, recog_data.operand,
recog_data.operand_loc,
recog_data.constraints,
- recog_data.operand_mode);
+ recog_data.operand_mode, NULL);
if (noperands > 0)
{
const char *p = recog_data.constraints[0];
Index: gcc/reload1.c
===================================================================
--- gcc/reload1.c.orig 2007-02-27 01:59:21.000000000 -0300
+++ gcc/reload1.c 2007-02-28 03:47:28.000000000 -0300
@@ -1365,7 +1365,7 @@ maybe_fix_stack_asms (void)
/* Get the operand values and constraints out of the insn. */
decode_asm_operands (pat, recog_data.operand, recog_data.operand_loc,
- constraints, operand_mode);
+ constraints, operand_mode, NULL);
/* For every operand, see what registers are allowed. */
for (i = 0; i < noperands; i++)
Index: gcc/rtl.def
===================================================================
--- gcc/rtl.def.orig 2007-02-05 23:01:27.000000000 -0200
+++ gcc/rtl.def 2007-02-28 02:55:51.000000000 -0300
@@ -168,15 +168,15 @@ DEF_RTL_EXPR(COND_EXEC, "cond_exec", "ee
/* Several operations to be done in parallel (perhaps under COND_EXEC). */
DEF_RTL_EXPR(PARALLEL, "parallel", "E", RTX_EXTRA)
+#ifdef USE_MAPPED_LOCATION
/* 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", RTX_EXTRA)
+DEF_RTL_EXPR(ASM_INPUT, "asm_input", "si", RTX_EXTRA)
-#ifdef USE_MAPPED_LOCATION
/* An assembler instruction with operands.
1st operand is the instruction template.
2nd operand is the constraint for the output.
@@ -190,6 +190,14 @@ DEF_RTL_EXPR(ASM_INPUT, "asm_input", "s"
6th is the source line number. */
DEF_RTL_EXPR(ASM_OPERANDS, "asm_operands", "ssiEEi", RTX_EXTRA)
#else
+/* 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", "ssi", RTX_EXTRA)
+
/* An assembler instruction with operands.
1st operand is the instruction template.
2nd operand is the constraint for the output.
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h.orig 2007-02-27 01:59:21.000000000 -0300
+++ gcc/rtl.h 2007-02-28 03:43:40.000000000 -0300
@@ -1090,9 +1090,12 @@ do { \
GET_MODE (XCVECEXP (RTX, 4, N, ASM_OPERANDS))
#ifdef USE_MAPPED_LOCATION
#define ASM_OPERANDS_SOURCE_LOCATION(RTX) XCUINT (RTX, 5, ASM_OPERANDS)
+#define ASM_INPUT_SOURCE_LOCATION(RTX) XCUINT (RTX, 1, ASM_INPUT)
#else
#define ASM_OPERANDS_SOURCE_FILE(RTX) XCSTR (RTX, 5, ASM_OPERANDS)
#define ASM_OPERANDS_SOURCE_LINE(RTX) XCINT (RTX, 6, ASM_OPERANDS)
+#define ASM_INPUT_SOURCE_FILE(RTX) XCSTR (RTX, 1, ASM_INPUT)
+#define ASM_INPUT_SOURCE_LINE(RTX) XCINT (RTX, 2, ASM_INPUT)
#endif
/* 1 if RTX is a mem that is statically allocated in read-only memory. */
@@ -1765,7 +1768,7 @@ extern void free_reg_info (void);
/* recog.c */
extern int asm_noperands (rtx);
extern const char *decode_asm_operands (rtx, rtx *, rtx **, const char **,
- enum machine_mode *);
+ enum machine_mode *, location_t *);
extern enum reg_class reg_preferred_class (int);
extern enum reg_class reg_alternate_class (int);
@@ -1862,7 +1865,17 @@ extern GTY(()) rtx return_address_pointe
#ifndef GENERATOR_FILE
#include "genrtl.h"
-#ifndef USE_MAPPED_LOCATION
+#undef gen_rtx_ASM_INPUT
+#ifdef USE_MAPPED_LOCATION
+#define gen_rtx_ASM_INPUT(MODE, ARG0) \
+ gen_rtx_fmt_si (ASM_INPUT, (MODE), (ARG0), 0)
+#define gen_rtx_ASM_INPUT_loc(MODE, ARG0, LOC) \
+ gen_rtx_fmt_si (ASM_INPUT, (MODE), (ARG0), (LOC))
+#else
+#define gen_rtx_ASM_INPUT(MODE, ARG0) \
+ gen_rtx_fmt_ssi (ASM_INPUT, (MODE), (ARG0), NULL, 0)
+#define gen_rtx_ASM_INPUT_loc(MODE, ARG0, LOC) \
+ gen_rtx_fmt_ssi (ASM_INPUT, (MODE), (ARG0), (LOC).file, (LOC).line)
#undef gen_rtx_ASM_OPERANDS
#define gen_rtx_ASM_OPERANDS(MODE, ARG0, ARG1, ARG2, ARG3, ARG4, LOC) \
gen_rtx_fmt_ssiEEsi (ASM_OPERANDS, (MODE), (ARG0), (ARG1), (ARG2), (ARG3), (ARG4), (LOC).file, (LOC).line)
Index: gcc/stmt.c
===================================================================
--- gcc/stmt.c.orig 2007-02-16 02:19:56.000000000 -0200
+++ gcc/stmt.c 2007-02-28 03:00:59.000000000 -0300
@@ -1,6 +1,6 @@
/* Expands front end tree to back end RTL for GCC
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GCC.
@@ -260,15 +260,16 @@ n_occurrences (int c, const char *s)
insn is volatile; don't optimize it. */
static void
-expand_asm (tree string, int vol)
+expand_asm_loc (tree string, int vol, location_t locus)
{
rtx body;
if (TREE_CODE (string) == ADDR_EXPR)
string = TREE_OPERAND (string, 0);
- body = gen_rtx_ASM_INPUT (VOIDmode,
- ggc_strdup (TREE_STRING_POINTER (string)));
+ body = gen_rtx_ASM_INPUT_loc (VOIDmode,
+ ggc_strdup (TREE_STRING_POINTER (string)),
+ locus);
MEM_VOLATILE_P (body) = vol;
@@ -1094,7 +1095,7 @@ expand_asm_expr (tree exp)
if (ASM_INPUT_P (exp))
{
- expand_asm (ASM_STRING (exp), ASM_VOLATILE_P (exp));
+ expand_asm_loc (ASM_STRING (exp), ASM_VOLATILE_P (exp), input_location);
return;
}
--
Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member http://www.fsfla.org/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}