DATA_ALIGNMENT vs. DECL_USER_ALIGNMENT
Ulrich Weigand
weigand@immd1.informatik.uni-erlangen.de
Thu Apr 10 16:20:00 GMT 2003
I wrote:
> For data labels, it would of course be possible to use
> some other means to load the address (e.g. from the literal
> pool); however as the backend has no way to find out for
> which labels this would be necessary, the alternative
> would mean not to use LARL for any label.
I've tried to identify symbols with forced 1-byte alignment
in encode_section_info, and mark them specically; this allows
me to avoid using LARL for those (and only those) symbols.
The patch below implements this; I'll commit this as soon
as testing is complete, because it fixes a bug in any case.
However, Ada bootstrap still fails, because it uses
inconsistent alignment flags for the same symbol between
different translation units: the elaboration check flag
variables are defined from within Ada sources, and marked
as forced 1-byte aligned there, but they are *referenced*
from within auto-generated C sources, and are declared
simply as 'extern char xxx;' there, without any forced
alignment specification.
This means that when compiling the C source that references
the variables, I do not know that they are in fact 1-byte
aligned. Do you think the backend should be able to cope
with even this scenario, or would you consider this a
frontend bug?
Bye,
Ulrich
ChangeLog:
* config/s390/s390.c (larl_operand): Do not allow symbols
marked with '@'.
(s390_encode_section_info): Mark symbols with forced 1-byte
alignment with '@'.
(s390_strip_name_encoding): Strip '@'.
(legitimize_pic_address): Handle symbols that are not valid
LARL operands in 64-bit mode.
Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.86
diff -c -p -r1.86 s390.c
*** gcc/config/s390/s390.c 1 Apr 2003 17:32:33 -0000 1.86
--- gcc/config/s390/s390.c 10 Apr 2003 02:21:28 -0000
*************** larl_operand (op, mode)
*** 1051,1056 ****
--- 1051,1057 ----
if (GET_CODE (op) == LABEL_REF)
return 1;
if (GET_CODE (op) == SYMBOL_REF
+ && XSTR (op, 0)[0] != '@'
&& !tls_symbolic_operand (op)
&& (!flag_pic || SYMBOL_REF_FLAG (op)
|| CONSTANT_POOL_ADDRESS_P (op)))
*************** larl_operand (op, mode)
*** 1074,1079 ****
--- 1075,1081 ----
if (GET_CODE (op) == LABEL_REF)
return 1;
if (GET_CODE (op) == SYMBOL_REF
+ && XSTR (op, 0)[0] != '@'
&& !tls_symbolic_operand (op)
&& (!flag_pic || SYMBOL_REF_FLAG (op)
|| CONSTANT_POOL_ADDRESS_P (op)))
*************** legitimize_pic_address (orig, reg)
*** 2179,2185 ****
|| CONSTANT_POOL_ADDRESS_P (addr))))
{
/* This is a local symbol. */
! if (TARGET_64BIT)
{
/* Access local symbols PC-relative via LARL.
This is the same as in the non-PIC case, so it is
--- 2181,2187 ----
|| CONSTANT_POOL_ADDRESS_P (addr))))
{
/* This is a local symbol. */
! if (TARGET_64BIT && larl_operand (addr, VOIDmode))
{
/* Access local symbols PC-relative via LARL.
This is the same as in the non-PIC case, so it is
*************** legitimize_pic_address (orig, reg)
*** 2191,2199 ****
rtx temp = reg? reg : gen_reg_rtx (Pmode);
! addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, addr), 100);
! addr = gen_rtx_CONST (SImode, addr);
! addr = force_const_mem (SImode, addr);
emit_move_insn (temp, addr);
base = gen_rtx_REG (Pmode, BASE_REGISTER);
--- 2193,2201 ----
rtx temp = reg? reg : gen_reg_rtx (Pmode);
! addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 100);
! addr = gen_rtx_CONST (Pmode, addr);
! addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
base = gen_rtx_REG (Pmode, BASE_REGISTER);
*************** legitimize_pic_address (orig, reg)
*** 2254,2262 ****
if (reload_in_progress || reload_completed)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
! addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, addr), 112);
! addr = gen_rtx_CONST (SImode, addr);
! addr = force_const_mem (SImode, addr);
emit_move_insn (temp, addr);
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
--- 2256,2264 ----
if (reload_in_progress || reload_completed)
regs_ever_live[PIC_OFFSET_TABLE_REGNUM] = 1;
! addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 112);
! addr = gen_rtx_CONST (Pmode, addr);
! addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
new = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, temp);
*************** legitimize_pic_address (orig, reg)
*** 2282,2288 ****
case 100:
case 112:
case 114:
! new = force_const_mem (SImode, orig);
break;
/* @GOTENT is OK as is. */
--- 2284,2290 ----
case 100:
case 112:
case 114:
! new = force_const_mem (Pmode, orig);
break;
/* @GOTENT is OK as is. */
*************** legitimize_pic_address (orig, reg)
*** 2297,2305 ****
rtx temp = reg? reg : gen_reg_rtx (Pmode);
addr = XVECEXP (addr, 0, 0);
! addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, addr), 114);
! addr = gen_rtx_CONST (SImode, addr);
! addr = force_const_mem (SImode, addr);
emit_move_insn (temp, addr);
base = gen_rtx_REG (Pmode, BASE_REGISTER);
--- 2299,2307 ----
rtx temp = reg? reg : gen_reg_rtx (Pmode);
addr = XVECEXP (addr, 0, 0);
! addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), 114);
! addr = gen_rtx_CONST (Pmode, addr);
! addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
base = gen_rtx_REG (Pmode, BASE_REGISTER);
*************** legitimize_pic_address (orig, reg)
*** 2333,2339 ****
|| CONSTANT_POOL_ADDRESS_P (op0))))
&& GET_CODE (op1) == CONST_INT)
{
! if (TARGET_64BIT)
{
if (INTVAL (op1) & 1)
{
--- 2335,2341 ----
|| CONSTANT_POOL_ADDRESS_P (op0))))
&& GET_CODE (op1) == CONST_INT)
{
! if (TARGET_64BIT && larl_operand (op0, VOIDmode))
{
if (INTVAL (op1) & 1)
{
*************** legitimize_pic_address (orig, reg)
*** 2370,2379 ****
rtx temp = reg? reg : gen_reg_rtx (Pmode);
! addr = gen_rtx_UNSPEC (SImode, gen_rtvec (1, op0), 100);
! addr = gen_rtx_PLUS (SImode, addr, op1);
! addr = gen_rtx_CONST (SImode, addr);
! addr = force_const_mem (SImode, addr);
emit_move_insn (temp, addr);
base = gen_rtx_REG (Pmode, BASE_REGISTER);
--- 2372,2381 ----
rtx temp = reg? reg : gen_reg_rtx (Pmode);
! addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), 100);
! addr = gen_rtx_PLUS (Pmode, addr, op1);
! addr = gen_rtx_CONST (Pmode, addr);
! addr = force_const_mem (Pmode, addr);
emit_move_insn (temp, addr);
base = gen_rtx_REG (Pmode, BASE_REGISTER);
*************** legitimize_pic_address (orig, reg)
*** 2399,2405 ****
if (XINT (op0, 1) != 100)
abort ();
! new = force_const_mem (SImode, orig);
}
/* Otherwise, compute the sum. */
--- 2401,2407 ----
if (XINT (op0, 1) != 100)
abort ();
! new = force_const_mem (Pmode, orig);
}
/* Otherwise, compute the sum. */
*************** s390_encode_section_info (decl, first)
*** 6480,6485 ****
--- 6482,6504 ----
XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 2 - 1);
}
+
+ /* If a variable has a forced alignment to < 2 bytes, mark it
+ with '@' to prevent it from being used as LARL operand. */
+
+ else if (TREE_CODE (decl) == VAR_DECL
+ && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16
+ && XSTR (symbol, 0)[0] != '@')
+ {
+ const char *symbol_str = XSTR (symbol, 0);
+ size_t len = strlen (symbol_str) + 1;
+ char *newstr = alloca (len + 1);
+
+ newstr[0] = '@';
+ memcpy (newstr + 1, symbol_str, len);
+
+ XSTR (symbol, 0) = ggc_alloc_string (newstr, len + 1 - 1);
+ }
}
/* Undo the above when printing symbol names. */
*************** s390_strip_name_encoding (str)
*** 6490,6495 ****
--- 6509,6516 ----
{
if (str[0] == '%')
str += 2;
+ if (str[0] == '@')
+ str += 1;
if (str[0] == '*')
str += 1;
return str;
--
Dr. Ulrich Weigand
weigand@informatik.uni-erlangen.de
More information about the Gcc
mailing list