Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions gcc/config/arc/arc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -386,27 +386,35 @@ legitimate_small_data_address_p (rtx x, machine_mode mode)
return SYMBOL_REF_SMALL_P (x);
case PLUS:
{
bool p0 = (GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
&& SYMBOL_REF_SMALL_P (XEXP (x, 0));
if ((GET_CODE (XEXP (x, 0)) != SYMBOL_REF)
|| !SYMBOL_REF_SMALL_P (XEXP (x, 0)))
return false;

/* If no constant then we cannot do small data. */
if (!CONST_INT_P (XEXP (x, 1)))
return false;

/* Small data relocs works with scalled addresses, check if
const int offset = INTVAL (XEXP (x, 1));
int size = GET_MODE_SIZE (mode);
size = size == 8 ? 4 : size;

/* Small data relocs works with scaled addresses, check if
the immediate fits the requirements. */
switch (GET_MODE_SIZE (mode))
switch (size)
{
case 1:
return p0;
break;
case 2:
return p0 && ((INTVAL (XEXP (x, 1)) & 0x1) == 0);
if ((offset & 0x1) == 0) break; else return false;
case 4:
case 8:
return p0 && ((INTVAL (XEXP (x, 1)) & 0x3) == 0);
if ((offset & 0x3) == 0) break; else return false;
default:
return false;
}

/* Reloc allows scaled signed 9 bits. */
const int v = (offset / size) >> 8;
return v == 0 || v == -1;
}
default:
return false;
Expand Down
17 changes: 17 additions & 0 deletions gcc/testsuite/gcc.target/arc/sdata-6.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* { dg-do compile } */
/* { dg-options "-O2 -msdata" } */

__attribute__((section(".sdata"))) int a[300];

int f (void)
{
return a[255];
}

int g (void)
{
return a[256];
}

/* { dg-final { scan-assembler "ld_s\\s+r0,\\\[gp,@a@sda\\+1020\\\]" } } */
/* { dg-final { scan-assembler "ld\\s+r0,\\\[@a\\+1024\\\]" } } */