enum cpp_ttype type;
type = pragma_lex (&ctable_index);
- if (type == CPP_NUMBER && tree_fits_uhwi_p (ctable_index))
+ if (type == CPP_NUMBER && tree_fits_shwi_p (ctable_index))
{
type = pragma_lex (&base_addr);
- if (type == CPP_NUMBER && tree_fits_uhwi_p (base_addr))
+ if (type == CPP_NUMBER && tree_fits_shwi_p (base_addr))
{
- unsigned HOST_WIDE_INT i = tree_to_uhwi (ctable_index);
- unsigned HOST_WIDE_INT base = tree_to_uhwi (base_addr);
+ HOST_WIDE_INT i = tree_to_shwi (ctable_index);
+ HOST_WIDE_INT base = sext_hwi (tree_to_shwi (base_addr),
+ POINTER_SIZE);
type = pragma_lex (&base_addr);
if (type != CPP_EOF)
error ("junk at end of %<#pragma CTABLE_ENTRY%>");
- else if (i >= ARRAY_SIZE (pru_ctable))
+ else if (!IN_RANGE (i, 0, ARRAY_SIZE (pru_ctable) - 1))
error ("%<CTABLE_ENTRY%> index %wd is not valid", i);
else if (pru_ctable[i].valid && pru_ctable[i].base != base)
error ("redefinition of %<CTABLE_ENTRY %wd%>", i);
+ else if (!IN_RANGE (base, INT32_MIN, INT32_MAX))
+ error ("%<CTABLE_ENTRY%> base address does not fit in 32-bits");
else
{
if (base & 0xff)
struct pru_ctable_entry {
bool valid;
- unsigned HOST_WIDE_INT base;
+ HOST_WIDE_INT base;
};
extern struct pru_ctable_entry pru_ctable[32];
return pru_regno_ok_for_base_p (regno, strict_p);
}
-extern int pru_get_ctable_exact_base_index (unsigned HOST_WIDE_INT caddr);
-extern int pru_get_ctable_base_index (unsigned HOST_WIDE_INT caddr);
-extern int pru_get_ctable_base_offset (unsigned HOST_WIDE_INT caddr);
+extern int pru_get_ctable_exact_base_index (HOST_WIDE_INT caddr);
+extern int pru_get_ctable_base_index (HOST_WIDE_INT caddr);
+extern int pru_get_ctable_base_offset (HOST_WIDE_INT caddr);
extern int pru_symref2ioregno (rtx op);
/* Recognize a CTABLE base address. Return CTABLE entry index, or -1 if
base was not found in the pragma-filled pru_ctable. */
int
-pru_get_ctable_exact_base_index (unsigned HOST_WIDE_INT caddr)
+pru_get_ctable_exact_base_index (HOST_WIDE_INT caddr)
{
unsigned int i;
/* Check if the given address can be addressed via CTABLE_BASE + UBYTE_OFFS,
and return the base CTABLE index if possible. */
int
-pru_get_ctable_base_index (unsigned HOST_WIDE_INT caddr)
+pru_get_ctable_base_index (HOST_WIDE_INT caddr)
{
unsigned int i;
/* Return the offset from some CTABLE base for this address. */
int
-pru_get_ctable_base_offset (unsigned HOST_WIDE_INT caddr)
+pru_get_ctable_base_offset (HOST_WIDE_INT caddr)
{
int i;
case CONST_INT:
{
- unsigned HOST_WIDE_INT caddr = INTVAL (op);
+ HOST_WIDE_INT caddr = INTVAL (op);
int base = pru_get_ctable_base_index (caddr);
int offs = pru_get_ctable_base_offset (caddr);
if (base < 0)
--- /dev/null
+/* Test for base addresses with bit 31 set (PR121124). */
+
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+/* -O1 in the options is significant. Without it LBCO/SBCO operations may
+ not be optimized to the respective instructions. */
+
+
+#pragma ctable_entry 12 0x80beef00
+
+unsigned int
+test_ctable (unsigned int val1, unsigned int val2)
+{
+ ((volatile unsigned short int *)0x80beef00)[0] = val2;
+ ((volatile unsigned int *)0x80beef00)[val1] = val2;
+ return ((volatile unsigned int *)0x80beef00)[5];
+}
+
+/* { dg-final { scan-assembler "sbco\\tr15.b\[012\]?, 12, 0, 2" } } */
+/* { dg-final { scan-assembler "sbco\\tr15.b0, 12, r14, 4" } } */
+/* { dg-final { scan-assembler "lbco\\tr14.b0, 12, 20, 4" } } */