Commit 9854d9ed by Richard Kenner

(print_operand): Sort all cases in alphabetical order.

(print_operand, case 'G'): New case.
(output_epilog): Know that "GNU Obj-C" is the language string for Objective-C.

From-SVN: r4100
parent 2afabb48
...@@ -709,13 +709,96 @@ print_operand (file, x, code) ...@@ -709,13 +709,96 @@ print_operand (file, x, code)
switch (code) switch (code)
{ {
case 'k': case 'A':
/* X must be a constant. Write the 1's complement of the /* If X is a constant integer whose low-order 5 bits are zero,
constant. */ write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
in the RS/6000 assembler where "sri" with a zero shift count
write a trash instruction. */
if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
fprintf (file, "l");
else
fprintf (file, "r");
return;
case 'b':
/* Low-order 16 bits of constant, unsigned. */
if (! INT_P (x)) if (! INT_P (x))
output_operand_lossage ("invalid %%k value"); output_operand_lossage ("invalid %%b value");
fprintf (file, "%d", ~ INT_LOWPART (x)); fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
return;
case 'C':
/* This is an optional cror needed for LE or GE floating-point
comparisons. Otherwise write nothing. */
if ((GET_CODE (x) == LE || GET_CODE (x) == GE)
&& GET_MODE (XEXP (x, 0)) == CCFPmode)
{
int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
base_bit + 2, base_bit + (GET_CODE (x) == GE));
}
return;
case 'D':
/* Similar, except that this is for an scc, so we must be able to
encode the test in a single bit that is one. We do the above
for any LE, GE, GEU, or LEU and invert the bit for NE. */
if (GET_CODE (x) == LE || GET_CODE (x) == GE
|| GET_CODE (x) == LEU || GET_CODE (x) == GEU)
{
int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
base_bit + 2,
base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
}
else if (GET_CODE (x) == NE)
{
int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68);
fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
base_bit + 2, base_bit + 2);
}
return;
case 'E':
/* X is a CR register. Print the number of the third bit of the CR */
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
output_operand_lossage ("invalid %%E value");
fprintf(file, "%d", 4 * (REGNO (x) - 68) + 3);
break;
case 'f':
/* X is a CR register. Print the shift count needed to move it
to the high-order four bits. */
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
output_operand_lossage ("invalid %%f value");
else
fprintf (file, "%d", 4 * (REGNO (x) - 68));
return;
case 'F':
/* Similar, but print the count for the rotate in the opposite
direction. */
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
output_operand_lossage ("invalid %%F value");
else
fprintf (file, "%d", 32 - 4 * (REGNO (x) - 68));
return;
case 'G':
/* X is a constant integer. If it is negative, print "m",
otherwise print "z". This is to make a aze or ame insn. */
if (GET_CODE (x) != CONST_INT)
output_operand_lossage ("invalid %%G value");
else if (INTVAL (x) >= 0)
fprintf (file, "z");
else
fprintf (file, "m");
return; return;
case 'h': case 'h':
...@@ -735,64 +818,55 @@ print_operand (file, x, code) ...@@ -735,64 +818,55 @@ print_operand (file, x, code)
fprintf (file, "%d", (INT_LOWPART (x) + 24) & 31); fprintf (file, "%d", (INT_LOWPART (x) + 24) & 31);
return; return;
case 'b': case 'I':
/* Low-order 16 bits of constant, unsigned. */ /* Print `i' if this is a constant, else nothing. */
if (! INT_P (x))
output_operand_lossage ("invalid %%b value");
fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
return;
case 'w':
/* If constant, low-order 16 bits of constant, signed. Otherwise, write
normally. */
if (INT_P (x)) if (INT_P (x))
fprintf (file, "%d", fprintf (file, "i");
(INT_LOWPART (x) & 0xffff) - 2 * (INT_LOWPART (x) & 0x8000));
else
print_operand (file, x, 0);
return; return;
case 'W': case 'j':
/* If constant, low-order 16 bits of constant, unsigned. /* Write the bit number in CCR for jump. */
Otherwise, write normally. */ i = ccr_bit (x, 0);
if (INT_P (x)) if (i == -1)
fprintf (file, "%d", INT_LOWPART (x) & 0xffff); output_operand_lossage ("invalid %%j code");
else else
print_operand (file, x, 0); fprintf (file, "%d", i);
return;
case 'u':
/* High-order 16 bits of constant. */
if (! INT_P (x))
output_operand_lossage ("invalid %%u value");
fprintf (file, "%d", (INT_LOWPART (x) >> 16) & 0xffff);
return; return;
case 's': case 'J':
/* Low 5 bits of 32 - value */ /* Similar, but add one for shift count in rlinm for scc and pass
if (! INT_P (x)) scc flag to `ccr_bit'. */
output_operand_lossage ("invalid %%s value"); i = ccr_bit (x, 1);
if (i == -1)
fprintf (file, "%d", (32 - INT_LOWPART (x)) & 31); output_operand_lossage ("invalid %%J code");
else
fprintf (file, "%d", i + 1);
return; return;
case 'S': case 'k':
/* Low 5 bits of 31 - value */ /* X must be a constant. Write the 1's complement of the
constant. */
if (! INT_P (x)) if (! INT_P (x))
output_operand_lossage ("invalid %%S value"); output_operand_lossage ("invalid %%k value");
fprintf (file, "%d", (31 - INT_LOWPART (x)) & 31); fprintf (file, "%d", ~ INT_LOWPART (x));
return; return;
case 'p': case 'L':
/* X is a CONST_INT that is a power of two. Output the logarithm. */ /* Write second word of DImode or DFmode reference. Works on register
if (! INT_P (x) or non-indexed memory only. */
|| (i = exact_log2 (INT_LOWPART (x))) < 0) if (GET_CODE (x) == REG)
output_operand_lossage ("invalid %%p value"); fprintf (file, "%d", REGNO (x) + 1);
else if (GET_CODE (x) == MEM)
fprintf (file, "%d", i); {
/* Handle possible auto-increment. Since it is pre-increment and
we have already done it, we can just use an offset of four. */
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
else
output_address (plus_constant (XEXP (x, 0), 4));
}
return; return;
case 'm': case 'm':
...@@ -866,60 +940,6 @@ print_operand (file, x, code) ...@@ -866,60 +940,6 @@ print_operand (file, x, code)
fprintf (file, "%d", i); fprintf (file, "%d", i);
return; return;
case 'f':
/* X is a CR register. Print the shift count needed to move it
to the high-order four bits. */
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
output_operand_lossage ("invalid %%f value");
else
fprintf (file, "%d", 4 * (REGNO (x) - 68));
return;
case 'F':
/* Similar, but print the count for the rotate in the opposite
direction. */
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
output_operand_lossage ("invalid %%F value");
else
fprintf (file, "%d", 32 - 4 * (REGNO (x) - 68));
return;
case 'E':
/* X is a CR register. Print the number of the third bit of the CR */
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
output_operand_lossage ("invalid %%E value");
fprintf(file, "%d", 4 * (REGNO (x) - 68) + 3);
break;
case 'R':
/* X is a CR register. Print the mask for `mtcrf'. */
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
output_operand_lossage ("invalid %%R value");
else
fprintf (file, "%d", 128 >> (REGNO (x) - 68));
return;
case 'X':
if (GET_CODE (x) == MEM
&& LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0)))
fprintf (file, "x");
return;
case 'U':
/* Print `u' if this has an auto-increment or auto-decrement. */
if (GET_CODE (x) == MEM
&& (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC))
fprintf (file, "u");
return;
case 'I':
/* Print `i' if this is a constant, else nothing. */
if (INT_P (x))
fprintf (file, "i");
return;
case 'N': case 'N':
/* Write the number of elements in the vector times 4. */ /* Write the number of elements in the vector times 4. */
if (GET_CODE (x) != PARALLEL) if (GET_CODE (x) != PARALLEL)
...@@ -936,6 +956,15 @@ print_operand (file, x, code) ...@@ -936,6 +956,15 @@ print_operand (file, x, code)
fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4); fprintf (file, "%d", (XVECLEN (x, 0) - 1) * 4);
return; return;
case 'p':
/* X is a CONST_INT that is a power of two. Output the logarithm. */
if (! INT_P (x)
|| (i = exact_log2 (INT_LOWPART (x))) < 0)
output_operand_lossage ("invalid %%p value");
fprintf (file, "%d", i);
return;
case 'P': case 'P':
/* The operand must be an indirect memory reference. The result /* The operand must be an indirect memory reference. The result
is the register number. */ is the register number. */
...@@ -946,49 +975,28 @@ print_operand (file, x, code) ...@@ -946,49 +975,28 @@ print_operand (file, x, code)
fprintf (file, "%d", REGNO (XEXP (x, 0))); fprintf (file, "%d", REGNO (XEXP (x, 0)));
return; return;
case 'L': case 'R':
/* Write second word of DImode or DFmode reference. Works on register /* X is a CR register. Print the mask for `mtcrf'. */
or non-indexed memory only. */ if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
if (GET_CODE (x) == REG) output_operand_lossage ("invalid %%R value");
fprintf (file, "%d", REGNO (x) + 1);
else if (GET_CODE (x) == MEM)
{
/* Handle possible auto-increment. Since it is pre-increment and
we have already done it, we can just use an offset of four. */
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
else else
output_address (plus_constant (XEXP (x, 0), 4)); fprintf (file, "%d", 128 >> (REGNO (x) - 68));
}
return; return;
case 'Y': case 's':
/* Similar, for third word of TImode */ /* Low 5 bits of 32 - value */
if (GET_CODE (x) == REG) if (! INT_P (x))
fprintf (file, "%d", REGNO (x) + 2); output_operand_lossage ("invalid %%s value");
else if (GET_CODE (x) == MEM)
{ fprintf (file, "%d", (32 - INT_LOWPART (x)) & 31);
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
else
output_address (plus_constant (XEXP (x, 0), 8));
}
return; return;
case 'Z': case 'S':
/* Similar, for last word of TImode. */ /* Low 5 bits of 31 - value */
if (GET_CODE (x) == REG) if (! INT_P (x))
fprintf (file, "%d", REGNO (x) + 3); output_operand_lossage ("invalid %%S value");
else if (GET_CODE (x) == MEM)
{ fprintf (file, "%d", (31 - INT_LOWPART (x)) & 31);
if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
else
output_address (plus_constant (XEXP (x, 0), 12));
}
return; return;
case 't': case 't':
...@@ -1024,58 +1032,58 @@ print_operand (file, x, code) ...@@ -1024,58 +1032,58 @@ print_operand (file, x, code)
fprintf (file, "12"); fprintf (file, "12");
return; return;
case 'j': case 'u':
/* Write the bit number in CCR for jump. */ /* High-order 16 bits of constant. */
i = ccr_bit (x, 0); if (! INT_P (x))
if (i == -1) output_operand_lossage ("invalid %%u value");
output_operand_lossage ("invalid %%j code");
else
fprintf (file, "%d", i);
return;
case 'J': fprintf (file, "%d", (INT_LOWPART (x) >> 16) & 0xffff);
/* Similar, but add one for shift count in rlinm for scc and pass
scc flag to `ccr_bit'. */
i = ccr_bit (x, 1);
if (i == -1)
output_operand_lossage ("invalid %%J code");
else
fprintf (file, "%d", i + 1);
return; return;
case 'C': case 'U':
/* This is an optional cror needed for LE or GE floating-point /* Print `u' if this has an auto-increment or auto-decrement. */
comparisons. Otherwise write nothing. */ if (GET_CODE (x) == MEM
if ((GET_CODE (x) == LE || GET_CODE (x) == GE) && (GET_CODE (XEXP (x, 0)) == PRE_INC
&& GET_MODE (XEXP (x, 0)) == CCFPmode) || GET_CODE (XEXP (x, 0)) == PRE_DEC))
{ fprintf (file, "u");
int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); return;
fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3, case 'w':
base_bit + 2, base_bit + (GET_CODE (x) == GE)); /* If constant, low-order 16 bits of constant, signed. Otherwise, write
} normally. */
if (INT_P (x))
fprintf (file, "%d",
(INT_LOWPART (x) & 0xffff) - 2 * (INT_LOWPART (x) & 0x8000));
else
print_operand (file, x, 0);
return; return;
case 'D': case 'W':
/* Similar, except that this is for an scc, so we must be able to /* If constant, low-order 16 bits of constant, unsigned.
encode the test in a single bit that is one. We do the above Otherwise, write normally. */
for any LE, GE, GEU, or LEU and invert the bit for NE. */ if (INT_P (x))
if (GET_CODE (x) == LE || GET_CODE (x) == GE fprintf (file, "%d", INT_LOWPART (x) & 0xffff);
|| GET_CODE (x) == LEU || GET_CODE (x) == GEU) else
{ print_operand (file, x, 0);
int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); return;
fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3, case 'X':
base_bit + 2, if (GET_CODE (x) == MEM
base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU)); && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0)))
} fprintf (file, "x");
return;
else if (GET_CODE (x) == NE) case 'Y':
/* Like 'L', for third word of TImode */
if (GET_CODE (x) == REG)
fprintf (file, "%d", REGNO (x) + 2);
else if (GET_CODE (x) == MEM)
{ {
int base_bit = 4 * (REGNO (XEXP (x, 0)) - 68); if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3, output_address (plus_constant (XEXP (XEXP (x, 0), 0), 8));
base_bit + 2, base_bit + 2); else
output_address (plus_constant (XEXP (x, 0), 8));
} }
return; return;
...@@ -1090,15 +1098,18 @@ print_operand (file, x, code) ...@@ -1090,15 +1098,18 @@ print_operand (file, x, code)
RS6000_OUTPUT_BASENAME (file, XSTR (x, 0)); RS6000_OUTPUT_BASENAME (file, XSTR (x, 0));
return; return;
case 'A': case 'Z':
/* If X is a constant integer whose low-order 5 bits are zero, /* Like 'L', for last word of TImode. */
write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug if (GET_CODE (x) == REG)
in the RS/6000 assembler where "sri" with a zero shift count fprintf (file, "%d", REGNO (x) + 3);
write a trash instruction. */ else if (GET_CODE (x) == MEM)
if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0) {
fprintf (file, "l"); if (GET_CODE (XEXP (x, 0)) == PRE_INC
|| GET_CODE (XEXP (x, 0)) == PRE_DEC)
output_address (plus_constant (XEXP (XEXP (x, 0), 0), 12));
else else
fprintf (file, "r"); output_address (plus_constant (XEXP (x, 0), 12));
}
return; return;
case 0: case 0:
...@@ -1441,9 +1452,9 @@ output_epilog (file, size) ...@@ -1441,9 +1452,9 @@ output_epilog (file, size)
/* Language type. Unfortunately, there doesn't seem to be any official way /* Language type. Unfortunately, there doesn't seem to be any official way
to get this info, so we use language_string. C is 0. C++ is 9. to get this info, so we use language_string. C is 0. C++ is 9.
No number defined for Obj-C, but it doesn't have its own No number defined for Obj-C, so use the value for C for now. */
language_string, so we can't detect it anyways. */ if (! strcmp (language_string, "GNU C")
if (! strcmp (language_string, "GNU C")) || ! strcmp (language_string, "GNU Obj-C"))
i = 0; i = 0;
else if (! strcmp (language_string, "GNU F77")) else if (! strcmp (language_string, "GNU F77"))
i = 1; i = 1;
......
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