Commit 07045266 by Richard Sandiford Committed by Richard Sandiford

mips.h (set_volatile): Delete.

gcc/
	* config/mips/mips.h (set_volatile): Delete.
	* config/mips/mips.c (set_volatile): Delete.
	(mips_print_operand_punctuation): New function, split out from
	print_operand.  Remove '%{', '%}', '%~', '%&' and '%!'.
	Use the same character ordering in the code and the comments.
	Use a recursive call to handle '*'.  Abort on unknown characters.
	(mips_init_print_operand_punct): New function, split out from
	override_options.
	(mips_print_int_branch_condition): New function, split out from
	print_operand.  Use GET_RTX_NAME.  Use output_operand_lossage
	to report unexpected codes.
	(mips_print_float_branch_condition): New function, split out from
	print_operand.  Use output_operand_lossage to report unexpected codes.
	(print_operand): Rework to use a case statement.  Use the
	same letter ordering in the code and the comments.  Use
	output_operand_lossage to report unexpected codes and
	reverse_condition to handle inverted branch conditions.
	(override_options): Use mips_init_print_operand_punct.

From-SVN: r129453
parent ab77a036
2007-10-18 Richard Sandiford <rsandifo@nildram.co.uk>
* config/mips/mips.h (set_volatile): Delete.
* config/mips/mips.c (set_volatile): Delete.
(mips_print_operand_punctuation): New function, split out from
print_operand. Remove '%{', '%}', '%~', '%&' and '%!'.
Use the same character ordering in the code and the comments.
Use a recursive call to handle '*'. Abort on unknown characters.
(mips_init_print_operand_punct): New function, split out from
override_options.
(mips_print_int_branch_condition): New function, split out from
print_operand. Use GET_RTX_NAME. Use output_operand_lossage
to report unexpected codes.
(mips_print_float_branch_condition): New function, split out from
print_operand. Use output_operand_lossage to report unexpected codes.
(print_operand): Rework to use a case statement. Use the
same letter ordering in the code and the comments. Use
output_operand_lossage to report unexpected codes and
reverse_condition to handle inverted branch conditions.
(override_options): Use mips_init_print_operand_punct.
2007-10-18 Richard Sandiford <rsandifo@nildram.co.uk>
* config/mips/mips.h: Move variable declarations to end of file and
enclose them all in #ifndef USED_FOR_TARGET.
* config/mips/mips.c: Reorder functions into more logical groups,
......@@ -446,7 +446,6 @@ int mips_dwarf_regno[FIRST_PSEUDO_REGISTER];
int set_noreorder;
int set_noat;
int set_nomacro;
int set_volatile;
/* The next branch instruction is a branch likely, not branch normal. */
int mips_branch_likely;
......@@ -6287,358 +6286,344 @@ print_operand_reloc (FILE *file, rtx op, enum mips_symbol_context context,
fputc (')', file);
}
/* Implement the PRINT_OPERAND macro. The MIPS-specific operand codes are:
'X' OP is CONST_INT, prints 32 bits in hexadecimal format = "0x%08x",
'x' OP is CONST_INT, prints 16 bits in hexadecimal format = "0x%04x",
'h' OP is HIGH, prints %hi(X),
'd' output integer constant in decimal,
'z' if the operand is 0, use $0 instead of normal operand.
'D' print second part of double-word register or memory operand.
'L' print low-order register of double-word register operand.
'M' print high-order register of double-word register operand.
'C' print part of opcode for a branch condition.
'F' print part of opcode for a floating-point branch condition.
'N' print part of opcode for a branch condition, inverted.
'W' print part of opcode for a floating-point branch condition, inverted.
'T' print 'f' for (eq:CC ...), 't' for (ne:CC ...),
'z' for (eq:?I ...), 'n' for (ne:?I ...).
't' like 'T', but with the EQ/NE cases reversed
'Y' for a CONST_INT X, print mips_fp_conditions[X]
'Z' print the operand and a comma for ISA_HAS_8CC, otherwise print nothing
'R' print the reloc associated with LO_SUM
'q' print DSP accumulator registers
/* Print the text for PRINT_OPERAND punctation character CH to FILE.
The punctuation characters are:
'(' Turn on .set noreorder
')' Turn on .set reorder
'[' Turn on .set noat
']' Turn on .set at
'<' Turn on .set nomacro
'>' Turn on .set macro
'{' Turn on .set volatile (not GAS)
'}' Turn on .set novolatile (not GAS)
'&' Turn on .set noreorder if filling delay slots
'*' Turn on both .set noreorder and .set nomacro if filling delay slots
'!' Turn on .set nomacro if filling delay slots
'#' Print nop if in a .set noreorder section.
'/' Like '#', but does nothing within a delayed branch sequence
'?' Print 'l' if we are to use a branch likely instead of normal branch.
'@' Print the name of the assembler temporary register (at or $1).
'(' Start a nested ".set noreorder" block.
')' End a nested ".set noreorder" block.
'[' Start a nested ".set noat" block.
']' End a nested ".set noat" block.
'<' Start a nested ".set nomacro" block.
'>' End a nested ".set nomacro" block.
'*' Behave like %(%< if generating a delayed-branch sequence.
'#' Print a nop if in a ".set noreorder" block.
'/' Like '#', but do nothing within a delayed-branch sequence.
'?' Print "l" if mips_branch_likely is true
'.' Print the name of the register with a hard-wired zero (zero or $0).
'@' Print the name of the assembler temporary register (at or $1).
'^' Print the name of the pic call-through register (t9 or $25).
'$' Print the name of the stack pointer register (sp or $29).
'+' Print the name of the gp register (usually gp or $28).
'~' Output a branch alignment to LABEL_ALIGN(NULL).
'|' Print .set push; .set mips2 if !ISA_HAS_LL_SC.
'-' Print .set pop under the same conditions for '|'. */
'$' Print the name of the stack pointer register (sp or $29).
'|' Print ".set push; .set mips2" if !ISA_HAS_LL_SC.
'-' Print ".set pop" under the same conditions for '|'.
void
print_operand (FILE *file, rtx op, int letter)
{
register enum rtx_code code;
See also mips_init_print_operand_pucnt. */
if (PRINT_OPERAND_PUNCT_VALID_P (letter))
static void
mips_print_operand_punctuation (FILE *file, int ch)
{
switch (ch)
{
switch (letter)
{
case '?':
if (mips_branch_likely)
putc ('l', file);
break;
case '(':
if (set_noreorder++ == 0)
fputs (".set\tnoreorder\n\t", file);
break;
case '@':
fputs (reg_names [GP_REG_FIRST + 1], file);
break;
case ')':
gcc_assert (set_noreorder > 0);
if (--set_noreorder == 0)
fputs ("\n\t.set\treorder", file);
break;
case '^':
fputs (reg_names [PIC_FUNCTION_ADDR_REGNUM], file);
break;
case '[':
if (set_noat++ == 0)
fputs (".set\tnoat\n\t", file);
break;
case '.':
fputs (reg_names [GP_REG_FIRST + 0], file);
break;
case ']':
gcc_assert (set_noat > 0);
if (--set_noat == 0)
fputs ("\n\t.set\tat", file);
break;
case '$':
fputs (reg_names[STACK_POINTER_REGNUM], file);
break;
case '<':
if (set_nomacro++ == 0)
fputs (".set\tnomacro\n\t", file);
break;
case '+':
fputs (reg_names[PIC_OFFSET_TABLE_REGNUM], file);
break;
case '>':
gcc_assert (set_nomacro > 0);
if (--set_nomacro == 0)
fputs ("\n\t.set\tmacro", file);
break;
case '&':
if (final_sequence != 0 && set_noreorder++ == 0)
fputs (".set\tnoreorder\n\t", file);
break;
case '*':
if (final_sequence != 0)
{
mips_print_operand_punctuation (file, '(');
mips_print_operand_punctuation (file, '<');
}
break;
case '*':
if (final_sequence != 0)
{
if (set_noreorder++ == 0)
fputs (".set\tnoreorder\n\t", file);
case '#':
if (set_noreorder != 0)
fputs ("\n\tnop", file);
break;
if (set_nomacro++ == 0)
fputs (".set\tnomacro\n\t", file);
}
break;
case '/':
/* Print an extra newline so that the delayed insn is separated
from the following ones. This looks neater and is consistent
with non-nop delayed sequences. */
if (set_noreorder != 0 && final_sequence == 0)
fputs ("\n\tnop\n", file);
break;
case '!':
if (final_sequence != 0 && set_nomacro++ == 0)
fputs ("\n\t.set\tnomacro", file);
break;
case '?':
if (mips_branch_likely)
putc ('l', file);
break;
case '#':
if (set_noreorder != 0)
fputs ("\n\tnop", file);
break;
case '.':
fputs (reg_names[GP_REG_FIRST + 0], file);
break;
case '/':
/* Print an extra newline so that the delayed insn is separated
from the following ones. This looks neater and is consistent
with non-nop delayed sequences. */
if (set_noreorder != 0 && final_sequence == 0)
fputs ("\n\tnop\n", file);
break;
case '@':
fputs (reg_names[GP_REG_FIRST + 1], file);
break;
case '(':
if (set_noreorder++ == 0)
fputs (".set\tnoreorder\n\t", file);
break;
case '^':
fputs (reg_names[PIC_FUNCTION_ADDR_REGNUM], file);
break;
case ')':
if (set_noreorder == 0)
error ("internal error: %%) found without a %%( in assembler pattern");
case '+':
fputs (reg_names[PIC_OFFSET_TABLE_REGNUM], file);
break;
else if (--set_noreorder == 0)
fputs ("\n\t.set\treorder", file);
case '$':
fputs (reg_names[STACK_POINTER_REGNUM], file);
break;
break;
case '|':
if (!ISA_HAS_LL_SC)
fputs (".set\tpush\n\t.set\tmips2\n\t", file);
break;
case '[':
if (set_noat++ == 0)
fputs (".set\tnoat\n\t", file);
break;
case '-':
if (!ISA_HAS_LL_SC)
fputs ("\n\t.set\tpop", file);
break;
case ']':
if (set_noat == 0)
error ("internal error: %%] found without a %%[ in assembler pattern");
else if (--set_noat == 0)
fputs ("\n\t.set\tat", file);
default:
gcc_unreachable ();
break;
}
}
break;
/* Initialize mips_print_operand_punct. */
case '<':
if (set_nomacro++ == 0)
fputs (".set\tnomacro\n\t", file);
break;
static void
mips_init_print_operand_punct (void)
{
const char *p;
case '>':
if (set_nomacro == 0)
error ("internal error: %%> found without a %%< in assembler pattern");
else if (--set_nomacro == 0)
fputs ("\n\t.set\tmacro", file);
for (p = "()[]<>*#/?.@^+$|-"; *p; p++)
mips_print_operand_punct[(unsigned char) *p] = true;
}
break;
/* PRINT_OPERAND prefix LETTER refers to the integer branch instruction
associated with condition CODE. Print the condition part of the
opcode to FILE. */
case '{':
if (set_volatile++ == 0)
fputs ("#.set\tvolatile\n\t", file);
break;
static void
mips_print_int_branch_condition (FILE *file, enum rtx_code code, int letter)
{
switch (code)
{
case EQ:
case NE:
case GT:
case GE:
case LT:
case LE:
case GTU:
case GEU:
case LTU:
case LEU:
/* Conveniently, the MIPS names for these conditions are the same
as their RTL equivalents. */
fputs (GET_RTX_NAME (code), file);
break;
case '}':
if (set_volatile == 0)
error ("internal error: %%} found without a %%{ in assembler pattern");
else if (--set_volatile == 0)
fputs ("\n\t#.set\tnovolatile", file);
default:
output_operand_lossage ("'%%%c' is not a valid operand prefix", letter);
break;
}
}
break;
/* Likewise floating-point branches. */
case '~':
{
if (align_labels_log > 0)
ASM_OUTPUT_ALIGN (file, align_labels_log);
}
break;
static void
mips_print_float_branch_condition (FILE *file, enum rtx_code code, int letter)
{
switch (code)
{
case EQ:
fputs ("c1f", file);
break;
case '|':
if (!ISA_HAS_LL_SC)
fputs (".set\tpush\n\t.set\tmips2\n\t", file);
break;
case NE:
fputs ("c1t", file);
break;
case '-':
if (!ISA_HAS_LL_SC)
fputs ("\n\t.set\tpop", file);
break;
default:
output_operand_lossage ("'%%%c' is not a valid operand prefix", letter);
break;
}
}
default:
error ("PRINT_OPERAND: unknown punctuation '%c'", letter);
break;
}
/* Implement the PRINT_OPERAND macro. The MIPS-specific operand codes are:
return;
}
'X' Print CONST_INT OP in hexadecimal format.
'x' Print the low 16 bits of CONST_INT OP in hexadecimal format.
'd' Print CONST_INT OP in decimal.
'h' Print the high-part relocation associated with OP, after stripping
any outermost HIGH.
'R' Print the low-part relocation associated with OP.
'C' Print the integer branch condition for comparison OP.
'N' Print the inverse of the integer branch condition for comparison OP.
'F' Print the FPU branch condition for comparison OP.
'W' Print the inverse of the FPU branch condition for comparison OP.
'T' Print 'f' for (eq:CC ...), 't' for (ne:CC ...),
'z' for (eq:?I ...), 'n' for (ne:?I ...).
't' Like 'T', but with the EQ/NE cases reversed
'Y' Print mips_fp_conditions[INTVAL (OP)]
'Z' Print OP and a comma for ISA_HAS_8CC, otherwise print nothing.
'q' Print a DSP accumulator register.
'D' Print the second part of a double-word register or memory operand.
'L' Print the low-order register in a double-word register operand.
'M' Print high-order register in a double-word register operand.
'z' Print $0 if OP is zero, otherwise print OP normally. */
void
print_operand (FILE *file, rtx op, int letter)
{
enum rtx_code code;
if (! op)
if (PRINT_OPERAND_PUNCT_VALID_P (letter))
{
error ("PRINT_OPERAND null pointer");
mips_print_operand_punctuation (file, letter);
return;
}
gcc_assert (op);
code = GET_CODE (op);
if (letter == 'C')
switch (code)
{
case EQ: fputs ("eq", file); break;
case NE: fputs ("ne", file); break;
case GT: fputs ("gt", file); break;
case GE: fputs ("ge", file); break;
case LT: fputs ("lt", file); break;
case LE: fputs ("le", file); break;
case GTU: fputs ("gtu", file); break;
case GEU: fputs ("geu", file); break;
case LTU: fputs ("ltu", file); break;
case LEU: fputs ("leu", file); break;
default:
fatal_insn ("PRINT_OPERAND, invalid insn for %%C", op);
}
else if (letter == 'N')
switch (code)
{
case EQ: fputs ("ne", file); break;
case NE: fputs ("eq", file); break;
case GT: fputs ("le", file); break;
case GE: fputs ("lt", file); break;
case LT: fputs ("ge", file); break;
case LE: fputs ("gt", file); break;
case GTU: fputs ("leu", file); break;
case GEU: fputs ("ltu", file); break;
case LTU: fputs ("geu", file); break;
case LEU: fputs ("gtu", file); break;
default:
fatal_insn ("PRINT_OPERAND, invalid insn for %%N", op);
}
switch (letter)
{
case 'X':
if (GET_CODE (op) == CONST_INT)
fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op));
else
output_operand_lossage ("invalid use of '%%%c'", letter);
break;
else if (letter == 'F')
switch (code)
{
case EQ: fputs ("c1f", file); break;
case NE: fputs ("c1t", file); break;
default:
fatal_insn ("PRINT_OPERAND, invalid insn for %%F", op);
}
case 'x':
if (GET_CODE (op) == CONST_INT)
fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op) & 0xffff);
else
output_operand_lossage ("invalid use of '%%%c'", letter);
break;
else if (letter == 'W')
switch (code)
{
case EQ: fputs ("c1t", file); break;
case NE: fputs ("c1f", file); break;
default:
fatal_insn ("PRINT_OPERAND, invalid insn for %%W", op);
}
case 'd':
if (GET_CODE (op) == CONST_INT)
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op));
else
output_operand_lossage ("invalid use of '%%%c'", letter);
break;
else if (letter == 'h')
{
if (GET_CODE (op) == HIGH)
case 'h':
if (code == HIGH)
op = XEXP (op, 0);
print_operand_reloc (file, op, SYMBOL_CONTEXT_LEA, mips_hi_relocs);
}
break;
case 'R':
print_operand_reloc (file, op, SYMBOL_CONTEXT_LEA, mips_lo_relocs);
break;
else if (letter == 'R')
print_operand_reloc (file, op, SYMBOL_CONTEXT_LEA, mips_lo_relocs);
case 'C':
mips_print_int_branch_condition (file, code, letter);
break;
else if (letter == 'Y')
{
if (GET_CODE (op) == CONST_INT
&& ((unsigned HOST_WIDE_INT) INTVAL (op)
< ARRAY_SIZE (mips_fp_conditions)))
fputs (mips_fp_conditions[INTVAL (op)], file);
case 'N':
mips_print_int_branch_condition (file, reverse_condition (code), letter);
break;
case 'F':
mips_print_float_branch_condition (file, code, letter);
break;
case 'W':
mips_print_float_branch_condition (file, reverse_condition (code),
letter);
break;
case 'T':
case 't':
{
int truth = (code == NE) == (letter == 'T');
fputc ("zfnt"[truth * 2 + (GET_MODE (op) == CCmode)], file);
}
break;
case 'Y':
if (code == CONST_INT && UINTVAL (op) < ARRAY_SIZE (mips_fp_conditions))
fputs (mips_fp_conditions[UINTVAL (op)], file);
else
output_operand_lossage ("invalid %%Y value");
}
output_operand_lossage ("'%%%c' is not a valid operand prefix",
letter);
break;
else if (letter == 'Z')
{
case 'Z':
if (ISA_HAS_8CC)
{
print_operand (file, op, 0);
fputc (',', file);
}
}
else if (letter == 'q')
{
int regnum;
if (code != REG)
fatal_insn ("PRINT_OPERAND, invalid insn for %%q", op);
break;
regnum = REGNO (op);
if (MD_REG_P (regnum))
case 'q':
if (code == REG && MD_REG_P (REGNO (op)))
fprintf (file, "$ac0");
else if (DSP_ACC_REG_P (regnum))
fprintf (file, "$ac%c", reg_names[regnum][3]);
else
fatal_insn ("PRINT_OPERAND, invalid insn for %%q", op);
}
else if (code == REG || code == SUBREG)
{
register int regnum;
if (code == REG)
regnum = REGNO (op);
else
regnum = true_regnum (op);
if ((letter == 'M' && ! WORDS_BIG_ENDIAN)
|| (letter == 'L' && WORDS_BIG_ENDIAN)
|| letter == 'D')
regnum++;
fprintf (file, "%s", reg_names[regnum]);
}
else if (code == MEM)
{
if (letter == 'D')
output_address (plus_constant (XEXP (op, 0), 4));
else if (code == REG && DSP_ACC_REG_P (REGNO (op)))
fprintf (file, "$ac%c", reg_names[REGNO (op)][3]);
else
output_address (XEXP (op, 0));
}
else if (letter == 'x' && GET_CODE (op) == CONST_INT)
fprintf (file, HOST_WIDE_INT_PRINT_HEX, 0xffff & INTVAL(op));
else if (letter == 'X' && GET_CODE(op) == CONST_INT)
fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op));
else if (letter == 'd' && GET_CODE(op) == CONST_INT)
fprintf (file, HOST_WIDE_INT_PRINT_DEC, (INTVAL(op)));
output_operand_lossage ("invalid use of '%%%c'", letter);
break;
else if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
fputs (reg_names[GP_REG_FIRST], file);
default:
switch (code)
{
case REG:
{
unsigned int regno = REGNO (op);
if ((letter == 'M' && TARGET_LITTLE_ENDIAN)
|| (letter == 'L' && TARGET_BIG_ENDIAN)
|| letter == 'D')
regno++;
fprintf (file, "%s", reg_names[regno]);
}
break;
else if (letter == 'd' || letter == 'x' || letter == 'X')
output_operand_lossage ("invalid use of %%d, %%x, or %%X");
case MEM:
if (letter == 'D')
output_address (plus_constant (XEXP (op, 0), 4));
else
output_address (XEXP (op, 0));
break;
else if (letter == 'T' || letter == 't')
{
int truth = (code == NE) == (letter == 'T');
fputc ("zfnt"[truth * 2 + (GET_MODE (op) == CCmode)], file);
default:
if (letter == 'z' && op == CONST0_RTX (GET_MODE (op)))
fputs (reg_names[GP_REG_FIRST], file);
else if (CONST_GP_P (op))
fputs (reg_names[GLOBAL_POINTER_REGNUM], file);
else
output_addr_const (file, mips_strip_unspec_address (op));
break;
}
}
else if (CONST_GP_P (op))
fputs (reg_names[GLOBAL_POINTER_REGNUM], file);
else
output_addr_const (file, mips_strip_unspec_address (op));
}
/* Output address operand X to FILE. */
void
......@@ -12318,28 +12303,7 @@ override_options (void)
if (TARGET_DSPR2)
target_flags |= MASK_DSP;
mips_print_operand_punct['?'] = 1;
mips_print_operand_punct['#'] = 1;
mips_print_operand_punct['/'] = 1;
mips_print_operand_punct['&'] = 1;
mips_print_operand_punct['!'] = 1;
mips_print_operand_punct['*'] = 1;
mips_print_operand_punct['@'] = 1;
mips_print_operand_punct['.'] = 1;
mips_print_operand_punct['('] = 1;
mips_print_operand_punct[')'] = 1;
mips_print_operand_punct['['] = 1;
mips_print_operand_punct[']'] = 1;
mips_print_operand_punct['<'] = 1;
mips_print_operand_punct['>'] = 1;
mips_print_operand_punct['{'] = 1;
mips_print_operand_punct['}'] = 1;
mips_print_operand_punct['^'] = 1;
mips_print_operand_punct['$'] = 1;
mips_print_operand_punct['+'] = 1;
mips_print_operand_punct['~'] = 1;
mips_print_operand_punct['|'] = 1;
mips_print_operand_punct['-'] = 1;
mips_init_print_operand_punct ();
/* Set up array to map GCC register number to debug register number.
Ignore the special purpose register numbers. */
......
......@@ -3070,7 +3070,6 @@ extern int sym_lineno; /* sgi next label # for each stmt */
extern int set_noreorder; /* # of nested .set noreorder's */
extern int set_nomacro; /* # of nested .set nomacro's */
extern int set_noat; /* # of nested .set noat's */
extern int set_volatile; /* # of nested .set volatile's */
extern int mips_branch_likely; /* emit 'l' after br (branch likely) */
extern int mips_dbx_regno[];
extern int mips_dwarf_regno[];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment