Commit bb4efbc8 by Richard Kenner

(output_move_dconst): New function.

(global_symbolic_reference_mentioned_p): New function.
(print_operand_address): Allow pc-relative mode not only
for {LABEL, SYMBOL}_REF but for CONST too. If compiling PIC,
transform "symbol+const(Rx)" to "const(symbol(sb))[Rx:b]".

From-SVN: r6606
parent ea1fd453
/* Subroutines for assembler code output on the NS32000. /* Subroutines for assembler code output on the NS32000.
Copyright (C) 1988 Free Software Foundation, Inc. Copyright (C) 1988, 1994 Free Software Foundation, Inc.
This file is part of GNU CC. This file is part of GNU CC.
...@@ -396,6 +396,38 @@ check_reg (oper, reg) ...@@ -396,6 +396,38 @@ check_reg (oper, reg)
} }
return 0; return 0;
} }
/* Returns 1 if OP contains a global symbol reference */
int
global_symbolic_reference_mentioned_p (op)
rtx op;
{
register char *fmt;
register int i;
if (GET_CODE (op) == SYMBOL_REF && ! SYMBOL_REF_FLAG (op))
return 1;
fmt = GET_RTX_FORMAT (GET_CODE (op));
for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
{
if (fmt[i] == 'E')
{
register int j;
for (j = XVECLEN (op, i) - 1; j >= 0; j--)
if (global_symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
return 1;
}
else if (fmt[i] == 'e'
&& global_symbolic_reference_mentioned_p (XEXP (op, i)))
return 1;
}
return 0;
}
/* PRINT_OPERAND is defined to call this function, /* PRINT_OPERAND is defined to call this function,
which is easier to debug than putting all the code in which is easier to debug than putting all the code in
...@@ -497,6 +529,7 @@ print_operand_address (file, addr) ...@@ -497,6 +529,7 @@ print_operand_address (file, addr)
static char scales[] = { 'b', 'w', 'd', 0, 'q', }; static char scales[] = { 'b', 'w', 'd', 0, 'q', };
rtx offset, base, indexexp, tmp; rtx offset, base, indexexp, tmp;
int scale; int scale;
extern int flag_pic;
if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_DEC) if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_DEC)
{ {
...@@ -560,9 +593,65 @@ print_operand_address (file, addr) ...@@ -560,9 +593,65 @@ print_operand_address (file, addr)
case MULT: case MULT:
indexexp = tmp; indexexp = tmp;
break; break;
case SYMBOL_REF:
if (flag_pic && ! CONSTANT_POOL_ADDRESS_P (tmp)
&& ! SYMBOL_REF_FLAG (tmp))
{
if (base)
{
if (indexexp)
abort ();
indexexp = base;
}
base = tmp;
break;
}
case CONST: case CONST:
if (flag_pic && GET_CODE (tmp) == CONST)
{
rtx sym, off, tmp1;
tmp1 = XEXP (tmp,0);
if (GET_CODE (tmp1) != PLUS)
abort ();
sym = XEXP (tmp1,0);
if (GET_CODE (sym) != SYMBOL_REF)
{
off = sym;
sym = XEXP (tmp1,1);
}
else
off = XEXP (tmp1,1);
if (GET_CODE (sym) == SYMBOL_REF)
{
if (GET_CODE (off) != CONST_INT)
abort ();
if (CONSTANT_POOL_ADDRESS_P (sym)
|| SYMBOL_REF_FLAG (sym))
{
SYMBOL_REF_FLAG (tmp) = 1;
}
else
{
if (base)
{
if (indexexp)
abort ();
indexexp = base;
}
if (offset != 0)
abort ();
base = sym;
offset = off;
break;
}
}
}
case CONST_INT: case CONST_INT:
case SYMBOL_REF:
case LABEL_REF: case LABEL_REF:
if (offset) if (offset)
offset = gen_rtx (PLUS, SImode, tmp, offset); offset = gen_rtx (PLUS, SImode, tmp, offset);
...@@ -613,6 +702,14 @@ print_operand_address (file, addr) ...@@ -613,6 +702,14 @@ print_operand_address (file, addr)
case REG: case REG:
fprintf (file, "(%s)", reg_names[REGNO (base)]); fprintf (file, "(%s)", reg_names[REGNO (base)]);
break; break;
case SYMBOL_REF:
if (! flag_pic)
abort ();
fprintf (file, "(");
output_addr_const (file, base);
fprintf (file, "(sb))");
break;
case MEM: case MEM:
addr = XEXP(base,0); addr = XEXP(base,0);
base = NULL; base = NULL;
...@@ -673,10 +770,15 @@ print_operand_address (file, addr) ...@@ -673,10 +770,15 @@ print_operand_address (file, addr)
default: default:
abort (); abort ();
} }
#if 0
else if (flag_pic && SYMBOL_REF_FLAG (offset))
fprintf (file, "(sb)");
#endif
#ifdef PC_RELATIVE #ifdef PC_RELATIVE
else /* no base */ else if (GET_CODE (offset) == LABEL_REF
if (GET_CODE (offset) == LABEL_REF || GET_CODE (offset) == SYMBOL_REF) || GET_CODE (offset) == SYMBOL_REF
fprintf (file, "(pc)"); || GET_CODE (offset) == CONST)
fprintf (file, "(pc)");
#endif #endif
#ifdef BASE_REG_NEEDED /* this is defined if the assembler always #ifdef BASE_REG_NEEDED /* this is defined if the assembler always
needs a base register */ needs a base register */
...@@ -760,3 +862,26 @@ output_shift_insn (operands) ...@@ -760,3 +862,26 @@ output_shift_insn (operands)
else return "ashd %2,%0"; else return "ashd %2,%0";
return "ashd %2,%0"; return "ashd %2,%0";
} }
char *
output_move_dconst (n, s)
int n;
char *s;
{
static char r[32];
if (n > -9 && n < 8)
strcpy (r, "movqd ");
else if (n > 0 && n < 256)
strcpy (r, "movzbd ");
else if (n > 0 && n < 65536)
strcpy (r, "movzwd ");
else if (n < 0 && n > -257)
strcpy (r, "movxbd ");
else if (n < 0 && n > -65537)
strcpy (r, "movxwd ");
else
strcpy (r, "movd ");
strcat (r, s);
return r;
}
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