Commit ceaaa9fe by Joern Rennecke Committed by Joern Rennecke

arc.h (SYMBOL_FLAG_CMEM): Define.

2016-04-28  Joern Rennecke  <joern.rennecke@embecosm.com>
            Andrew Burgess  <andrew.burgess@embecosm.com>
gcc:
        * config/arc/arc.h (SYMBOL_FLAG_CMEM): Define.
        (TARGET_NPS_CMEM_DEFAULT): Provide default definition.
        * config/arc/arc.c (arc_address_cost): Return 0 for cmem_address.
        (arc_encode_section_info): Set SYMBOL_FLAG_CMEM where indicated.
        * config/arc/arc.opt (mcmem): New option.
        * config/arc/arc.md (*extendqihi2_i): Add r/Uex alternative,
        supply length for r/m alternative.
        (*extendqisi2_ac): Likewise.
        (*extendhisi2_i): Add r/Uex alternative, supply length for r/m and
        r/Uex alternative.
        (movqi_insn): Add r/Ucm and Ucm/?Rac alternatives.
        (movhi_insn): Likewise.
        (movsi_insn): Add r/Ucm,Ucm/w alternatives.
        (*zero_extendqihi2_i): Add r/Ucm alternative.
        (*zero_extendqisi2_ac): Likewise.
        (*zero_extendhisi2_i): Likewise.
        * config/arc/constraints.md (Uex): New memory constraint.
        (Ucm): New define_constraint.
        * config/arc/predicates.md (long_immediate_loadstore_operand):
        Return 0 for MEM with cmem_address address.
        (cmem_address_0): New predicates.
        (cmem_address_1): Likewise.
        (cmem_address_2): Likewise.
        (cmem_address): Likewise.
gcc/testsuite:
        * gcc.target/arc/cmem-1.c: New file.
        * gcc.target/arc/cmem-2.c: New file.
        * gcc.target/arc/cmem-3.c: New file.
        * gcc.target/arc/cmem-4.c: New file.
        * gcc.target/arc/cmem-5.c: New file.
        * gcc.target/arc/cmem-6.c: New file.
        * gcc.target/arc/cmem-7.c: New file.
        * gcc.target/arc/cmem-ld.inc: New file.
        * gcc.target/arc/cmem-st.inc: New file.

Co-Authored-By: Andrew Burgess <andrew.burgess@embecosm.com>

From-SVN: r235595
parent dc236a9d
2016-04-28 Joern Rennecke <joern.rennecke@embecosm.com>
Andrew Burgess <andrew.burgess@embecosm.com>
* config/arc/arc.c (arc_conditional_register_usage): Take
TARGET_RRQ_CLASS into account.
(arc_print_operand): Support printing 'p' and 's' operands.
* config/arc/arc.h (TARGET_NPS_BITOPS_DEFAULT): Provide default
as 0.
(TARGET_RRQ_CLASS): Define.
(IS_POWEROF2_OR_0_P): Define.
* config/arc/arc.md (*movsi_insn): Add w/Clo, w/Chi, and w/Cbi
alternatives.
(*tst_movb): New define_insn.
(*tst): Avoid recognition if it could prevent '*tst_movb'
combination; replace c/CnL with c/Chs alternative.
(*tst_bitfield_tst): New define_insn.
(*tst_bitfield_asr): New define_insn.
(*tst_bitfield): New define_insn.
(andsi3_i): Add Rrq variant.
(extzv): New define_expand.
(insv): New define_expand.
(*insv_i): New define_insn.
(*movb): New define_insn.
(*movb_signed): New define_insn.
(*movb_high): New define_insn.
(*movb_high_signed): New define_insn.
(*movb_high_signed + 1): New define_split pattern.
(*mrgb): New define_insn.
(*mrgb + 1): New define_peephole2 pattern.
(*mrgb + 2): New define_peephole2 pattern.
* config/arc/arc.opt (mbitops): New option for nps400, uses
TARGET_NPS_BITOPS_DEFAULT.
* config/arc/constraints.md (q): Make register class conditional.
(Rrq): New register constraint.
(Chs): New constraint.
(Clo): New constraint.
(Chi): New constraint.
(Cbf): New constraint.
(Cbn): New constraint.
(C18): New constraint.
(Cbi): New constraint.
2016-04-28 Segher Boessenkool <segher@kernel.crashing.org> 2016-04-28 Segher Boessenkool <segher@kernel.crashing.org>
* cfganal.c (bitmap_intersection_of_succs): Delete assert checking * cfganal.c (bitmap_intersection_of_succs): Delete assert checking
......
...@@ -1430,7 +1430,8 @@ arc_conditional_register_usage (void) ...@@ -1430,7 +1430,8 @@ arc_conditional_register_usage (void)
{ {
if (i < 29) if (i < 29)
{ {
if (TARGET_Q_CLASS && ((i <= 3) || ((i >= 12) && (i <= 15)))) if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
&& ((i <= 3) || ((i >= 12) && (i <= 15))))
arc_regno_reg_class[i] = ARCOMPACT16_REGS; arc_regno_reg_class[i] = ARCOMPACT16_REGS;
else else
arc_regno_reg_class[i] = GENERAL_REGS; arc_regno_reg_class[i] = GENERAL_REGS;
...@@ -1447,12 +1448,12 @@ arc_conditional_register_usage (void) ...@@ -1447,12 +1448,12 @@ arc_conditional_register_usage (void)
arc_regno_reg_class[i] = NO_REGS; arc_regno_reg_class[i] = NO_REGS;
} }
/* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS has not been activated. */ /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
has not been activated. */
if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS)
CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
if (!TARGET_Q_CLASS) if (!TARGET_Q_CLASS)
{ CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
}
gcc_assert (FIRST_PSEUDO_REGISTER >= 144); gcc_assert (FIRST_PSEUDO_REGISTER >= 144);
...@@ -2994,6 +2995,8 @@ static int output_scaled = 0; ...@@ -2994,6 +2995,8 @@ static int output_scaled = 0;
'Z': log2(x+1)-1 'Z': log2(x+1)-1
'z': log2 'z': log2
'M': log2(~x) 'M': log2(~x)
'p': bit Position of lsb
's': size of bit field
'#': condbranch delay slot suffix '#': condbranch delay slot suffix
'*': jump delay slot suffix '*': jump delay slot suffix
'?' : nonjump-insn suffix for conditional execution or short instruction '?' : nonjump-insn suffix for conditional execution or short instruction
...@@ -3044,6 +3047,24 @@ arc_print_operand (FILE *file, rtx x, int code) ...@@ -3044,6 +3047,24 @@ arc_print_operand (FILE *file, rtx x, int code)
return; return;
case 'p':
if (GET_CODE (x) == CONST_INT)
fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
else
output_operand_lossage ("invalid operand to %%p code");
return;
case 's':
if (GET_CODE (x) == CONST_INT)
{
HOST_WIDE_INT i = INTVAL (x);
HOST_WIDE_INT s = exact_log2 (i & -i);
fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
}
else
output_operand_lossage ("invalid operand to %%s code");
return;
case '#' : case '#' :
/* Conditional branches depending on condition codes. /* Conditional branches depending on condition codes.
Note that this is only for branches that were known to depend on Note that this is only for branches that were known to depend on
......
...@@ -326,10 +326,18 @@ along with GCC; see the file COPYING3. If not see ...@@ -326,10 +326,18 @@ along with GCC; see the file COPYING3. If not see
#define UNALIGNED_ACCESS_DEFAULT 0 #define UNALIGNED_ACCESS_DEFAULT 0
#endif #endif
#ifndef TARGET_NPS_BITOPS_DEFAULT
#define TARGET_NPS_BITOPS_DEFAULT 0
#endif
#ifndef TARGET_NPS_CMEM_DEFAULT #ifndef TARGET_NPS_CMEM_DEFAULT
#define TARGET_NPS_CMEM_DEFAULT 0 #define TARGET_NPS_CMEM_DEFAULT 0
#endif #endif
/* Enable the RRQ instruction alternatives. */
#define TARGET_RRQ_CLASS TARGET_NPS_BITOPS
/* Target machine storage layout. */ /* Target machine storage layout. */
/* We want zero_extract to mean the same /* We want zero_extract to mean the same
...@@ -1033,6 +1041,7 @@ extern int arc_initial_elimination_offset(int from, int to); ...@@ -1033,6 +1041,7 @@ extern int arc_initial_elimination_offset(int from, int to);
/* Is the argument a const_int rtx, containing an exact power of 2 */ /* Is the argument a const_int rtx, containing an exact power of 2 */
#define IS_POWEROF2_P(X) (! ( (X) & ((X) - 1)) && (X)) #define IS_POWEROF2_P(X) (! ( (X) & ((X) - 1)) && (X))
#define IS_POWEROF2_OR_0_P(X) (! ( (X) & ((X) - 1)))
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
and check its validity for a certain class. and check its validity for a certain class.
......
...@@ -470,6 +470,10 @@ Specify thread pointer register number ...@@ -470,6 +470,10 @@ Specify thread pointer register number
mtp-regno=none mtp-regno=none
Target RejectNegative Var(arc_tp_regno,-1) Target RejectNegative Var(arc_tp_regno,-1)
mbitops
Target Report Var(TARGET_NPS_BITOPS) Init(TARGET_NPS_BITOPS_DEFAULT)
Enable use of NPS400 bit operations.
mcmem mcmem
Target Report Var(TARGET_NPS_CMEM) Init(TARGET_NPS_CMEM_DEFAULT) Target Report Var(TARGET_NPS_CMEM) Init(TARGET_NPS_CMEM_DEFAULT)
Enable use of NPS400 xld/xst extension. Enable use of NPS400 xld/xst extension.
......
...@@ -66,10 +66,18 @@ ...@@ -66,10 +66,18 @@
Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30}, Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30},
@code{blink}:@code{r31},") @code{blink}:@code{r31},")
(define_register_constraint "q" "ARCOMPACT16_REGS" (define_register_constraint "q" "TARGET_Q_CLASS ? ARCOMPACT16_REGS : NO_REGS"
"Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3}, "Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3},
@code{r12}-@code{r15}") @code{r12}-@code{r15}")
; NPS400 bitfield instructions require registers from the r0-r3,r12-r15
; range, and thus we need a register class and constraint that works
; independently of size optimization.
(define_register_constraint
"Rrq" "TARGET_RRQ_CLASS ? ARCOMPACT16_REGS : NO_REGS"
"Registers usable in NPS400 bitfield instructions: @code{r0}-@code{r3},
@code{r12}-@code{r15}")
(define_register_constraint "e" "AC16_BASE_REGS" (define_register_constraint "e" "AC16_BASE_REGS"
"Registers usable as base-regs of memory addresses in ARCompact 16-bit memory "Registers usable as base-regs of memory addresses in ARCompact 16-bit memory
instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}") instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}")
...@@ -236,12 +244,60 @@ ...@@ -236,12 +244,60 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test "ival == 0xff || ival == 0xffff"))) (match_test "ival == 0xff || ival == 0xffff")))
(define_constraint "Chs"
"@internal
constant for a highpart that can be checked with a shift (asr.f 0,rn,m)"
(and (match_code "const_int")
(match_test "IS_POWEROF2_P (-ival)")))
(define_constraint "Clo"
"@internal
constant that fits into 16 lower bits, for movl"
(and (match_code "const_int")
(match_test "TARGET_NPS_BITOPS")
(match_test "(ival & ~0xffffU) == 0")))
(define_constraint "Chi"
"@internal
constant that fits into 16 higher bits, for movh_i"
(and (match_code "const_int")
(match_test "TARGET_NPS_BITOPS")
(match_test "trunc_int_for_mode (ival >> 16, HImode) << 16 == ival")))
(define_constraint "Cbf"
"@internal
a mask for a bit field, for AND using movb_i"
(and (match_code "const_int")
(match_test "TARGET_NPS_BITOPS")
(match_test "IS_POWEROF2_OR_0_P (ival + (ival & -ival))")))
(define_constraint "Cbn"
"@internal
a constant integer, valid only if TARGET_NPS_BITOPS is true"
(and (match_code "const_int")
(match_test "TARGET_NPS_BITOPS")))
(define_constraint "C18"
"@internal
1,2,4 or 8"
(and (match_code "const_int")
(match_test "ival == 1 || ival == 2 || ival == 4 || ival == 8")))
(define_constraint "Crr" (define_constraint "Crr"
"@internal "@internal
constant that can be loaded with ror b,u6" constant that can be loaded with ror b,u6"
(and (match_code "const_int") (and (match_code "const_int")
(match_test "(ival & ~0x8000001f) == 0 && !arc_ccfsm_cond_exec_p ()"))) (match_test "(ival & ~0x8000001f) == 0 && !arc_ccfsm_cond_exec_p ()")))
(define_constraint "Cbi"
"@internal
constant that can be loaded with movbi.cl"
(and (match_code "const_int")
(match_test "TARGET_NPS_BITOPS")
(match_test "!ival
|| ((ival & 0xffffffffUL) >> exact_log2 (ival & -ival)
<= 0xff)")))
;; Floating-point constraints ;; Floating-point constraints
(define_constraint "G" (define_constraint "G"
......
2016-04-28 Joern Rennecke <joern.rennecke@embecosm.com> 2016-04-28 Joern Rennecke <joern.rennecke@embecosm.com>
Andrew Burgess <andrew.burgess@embecosm.com> Andrew Burgess <andrew.burgess@embecosm.com>
* gcc.target/arc/extzv-1.c: New file.
* gcc.target/arc/insv-1.c: New file.
* gcc.target/arc/insv-2.c: New file.
* gcc.target/arc/movb-1.c: New file.
* gcc.target/arc/movb-2.c: New file.
* gcc.target/arc/movb-3.c: New file.
* gcc.target/arc/movb-4.c: New file.
* gcc.target/arc/movb-5.c: New file.
* gcc.target/arc/movb_cl-1.c: New file.
* gcc.target/arc/movb_cl-2.c: New file.
* gcc.target/arc/movbi_cl-1.c: New file.
* gcc.target/arc/movl-1.c: New file.
2016-04-28 Joern Rennecke <joern.rennecke@embecosm.com>
Andrew Burgess <andrew.burgess@embecosm.com>
* gcc.target/arc/cmem-1.c: New file. * gcc.target/arc/cmem-1.c: New file.
* gcc.target/arc/cmem-2.c: New file. * gcc.target/arc/cmem-2.c: New file.
* gcc.target/arc/cmem-3.c: New file. * gcc.target/arc/cmem-3.c: New file.
......
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct foo { unsigned a: 3, b: 5, c: 24; };
int
f (struct foo i)
{
return i.b;
}
/* { dg-final { scan-assembler "movb\.cl" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
/* ??? Irrespective of insn set, generated code for this is a mess. */
struct foo { unsigned a: 3, b: 8, c: 21; };
struct foo
f (struct foo i)
{
i.b = 42;
return i;
}
struct foo
g (struct foo i, int j)
{
i.b = j;
return i;
}
/* { dg-final { scan-assembler "movbi\[ \t\]" } } */
/* { dg-final { scan-assembler "movb\[ \t\]" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct foo { unsigned a: 3, b: 8, c: 21; } bar;
void
f (void)
{
bar.b = 42;
}
void
g (int j)
{
bar.b = j;
}
/* { dg-final { scan-assembler "movbi\[ \t\]" } } */
/* { dg-final { scan-assembler "movb\[ \t\]" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct { unsigned a: 5, b: 8, c: 19; } foo;
struct { unsigned a: 3, b: 8, c: 21; } bar;
void
f (void)
{
bar.b = foo.b;
}
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct { unsigned a: 23, b: 9; } foo;
struct { unsigned a: 23, b: 9; } bar;
void
f (void)
{
bar.b = foo.b;
}
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct { int a: 23, b: 9; } foo;
struct { int a: 23, b: 9; } bar;
void
f (void)
{
bar.a = foo.a;
}
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *23" { target arc-*-* } } } */
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *9, *9, *23" { target arceb-*-* } } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct { int a: 13, b: 19; } foo;
struct { int a: 13, b: 19; } bar;
void
f (void)
{
bar.b = foo.b;
}
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *13, *13, *19" { target arc-*-* } } } */
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *19" { target arceb-*-* } } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
struct { int a: 23, b: 9; } foo;
struct { int a: 23, b: 9; } bar;
void
f (void)
{
bar.b = foo.b;
}
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */
/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
int
f (int i)
{
return i & 0x0ffff000;
}
/* { dg-final { scan-assembler "movb\.cl" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
extern void g (void);
int
f (int i)
{
if (i & 0x0ffff000)
g ();
}
/* { dg-final { scan-assembler "movb\.f\.cl" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
int
f (int i)
{
return 0x6e00;
}
/* { dg-final { scan-assembler "mov(bi|l)\.cl" } } */
/* { dg-do compile } */
/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
int
f (void)
{
return 0xd00d;
}
int
g (void)
{
return 0x7ff00000;
}
/* { dg-final { scan-assembler "movl\.cl\[ \t\]" } } */
/* { dg-final { scan-assembler "movh\.cl\[ \t\]" } } */
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