aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorClaudiu Zissulescu <claziss@synopsys.com>2018-01-26 12:33:22 +0100
committerClaudiu Zissulescu <claziss@gcc.gnu.org>2018-01-26 12:33:22 +0100
commit6b55f8c92b1ea138ac851389c456820fde8cf026 (patch)
tree70d2aef6a7c1b68ee263d94226cfc33eb32ae1c1 /gcc/config
parentc921c45fdb3b6a6106e2de835a4a9e0e44b7afaf (diff)
downloadgcc-6b55f8c92b1ea138ac851389c456820fde8cf026.zip
gcc-6b55f8c92b1ea138ac851389c456820fde8cf026.tar.gz
gcc-6b55f8c92b1ea138ac851389c456820fde8cf026.tar.bz2
[ARC] Add JLI support.
The ARCv2 ISA provides the JLI instruction, which is two-byte instructions that can be used to reduce code size in an application. To make use of it, we provide two new function attributes 'jli_always' and 'jli_fixed' which will force the compiler to call the indicated function using a jli_s instruction. The compiler also generates the entries in the JLI table for the case when we use 'jli_always' attribute. In the case of 'jli_fixed' the compiler assumes a fixed position of the function into JLI table. Thus, the user needs to provide an assembly file with the JLI table for the final link. This is usefully when we want to have a table in ROM and a second table in the RAM memory. The jli instruction usage can be also forced without the need to annotate the source code via '-mjli-always' command. gcc/ 2018-01-26 Claudiu Zissulescu <claziss@synopsys.com> John Eric Martin <John.Martin@emmicro-us.com> * config/arc/arc-protos.h: Add arc_is_jli_call_p proto. * config/arc/arc.c (_arc_jli_section): New struct. (arc_jli_section): New type. (rc_jli_sections): New static variable. (arc_handle_jli_attribute): New function. (arc_attribute_table): Add jli_always and jli_fixed attribute. (arc_file_end): New function. (TARGET_ASM_FILE_END): Define. (arc_print_operand): Reuse 'S' letter for JLI output instruction. (arc_add_jli_section): New function. (jli_call_scan): Likewise. (arc_reorg): Call jli_call_scan. (arc_output_addsi): Remove 'S' from printing asm operand. (arc_is_jli_call_p): New function. * config/arc/arc.md (movqi_insn): Remove 'S' from printing asm operand. (movhi_insn): Likewise. (movsi_insn): Likewise. (movsi_set_cc_insn): Likewise. (loadqi_update): Likewise. (load_zeroextendqisi_update): Likewise. (load_signextendqisi_update): Likewise. (loadhi_update): Likewise. (load_zeroextendhisi_update): Likewise. (load_signextendhisi_update): Likewise. (loadsi_update): Likewise. (loadsf_update): Likewise. (movsicc_insn): Likewise. (bset_insn): Likewise. (bxor_insn): Likewise. (bclr_insn): Likewise. (bmsk_insn): Likewise. (bicsi3_insn): Likewise. (cmpsi_cc_c_insn): Likewise. (movsi_ne): Likewise. (movsi_cond_exec): Likewise. (clrsbsi2): Likewise. (norm_f): Likewise. (normw): Likewise. (swap): Likewise. (divaw): Likewise. (flag): Likewise. (sr): Likewise. (kflag): Likewise. (ffs): Likewise. (ffs_f): Likewise. (fls): Likewise. (call_i): Remove 'S' asm letter, add jli instruction. (call_value_i): Likewise. * config/arc/arc.op (mjli-always): New option. * config/arc/constraints.md (Cji): New constraint. * config/arc/fpx.md (addsf3_fpx): Remove 'S' from printing asm operand. (subsf3_fpx): Likewise. (mulsf3_fpx): Likewise. * config/arc/simdext.md (vendrec_insn): Remove 'S' from printing asm operand. * doc/extend.texi (ARC): Document 'jli-always' and 'jli-fixed' function attrbutes. * doc/invoke.texi (ARC): Document mjli-always option. gcc/testsuite 2018-01-26 Claudiu Zissulescu <claziss@synopsys.com> * gcc.target/arc/jli-1.c: New file. * gcc.target/arc/jli-2.c: Likewise. Co-Authored-By: John Eric Martin <John.Martin@emmicro-us.com> From-SVN: r257081
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arc/arc-protos.h2
-rw-r--r--gcc/config/arc/arc.c220
-rw-r--r--gcc/config/arc/arc.md128
-rw-r--r--gcc/config/arc/arc.opt4
-rw-r--r--gcc/config/arc/constraints.md6
-rw-r--r--gcc/config/arc/elf.h3
-rw-r--r--gcc/config/arc/fpx.md18
-rw-r--r--gcc/config/arc/linux.h1
-rw-r--r--gcc/config/arc/simdext.md2
9 files changed, 304 insertions, 80 deletions
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index d4315b3..7274fe0 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -116,3 +116,5 @@ extern void arc_secondary_reload_conv (rtx, rtx, rtx, bool);
extern void arc_cpu_cpp_builtins (cpp_reader *);
extern bool arc_store_addr_hazard_p (rtx_insn *, rtx_insn *);
extern rtx arc_eh_return_address_location (void);
+extern bool arc_is_jli_call_p (rtx);
+extern void arc_file_end (void);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index c794791..78cf323 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -73,6 +73,14 @@ along with GCC; see the file COPYING3. If not see
static char arc_cpu_name[10] = "";
static const char *arc_cpu_string = arc_cpu_name;
+typedef struct GTY (()) _arc_jli_section
+{
+ const char *name;
+ struct _arc_jli_section *next;
+} arc_jli_section;
+
+static arc_jli_section *arc_jli_sections = NULL;
+
/* Track which regs are set fixed/call saved/call used from commnad line. */
HARD_REG_SET overrideregs;
@@ -217,6 +225,8 @@ static int get_arc_condition_code (rtx);
static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
+static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
+
/* Initialized arc_attribute_table to NULL since arc doesnot have any
machine specific supported attributes. */
@@ -240,6 +250,13 @@ const struct attribute_spec arc_attribute_table[] =
by the compiler. */
{ "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute,
NULL },
+ /* Functions calls made using jli instruction. The pointer in JLI
+ table is found latter. */
+ { "jli_always", 0, 0, false, true, true, NULL, NULL },
+ /* Functions calls made using jli instruction. The pointer in JLI
+ table is given as input parameter. */
+ { "jli_fixed", 1, 1, false, true, true, arc_handle_jli_attribute,
+ NULL },
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
static int arc_comp_type_attributes (const_tree, const_tree);
@@ -3754,7 +3771,7 @@ static int output_scaled = 0;
'd'
'D'
'R': Second word
- 'S'
+ 'S': JLI instruction
'B': Branch comparison operand - suppress sda reference
'H': Most significant word
'L': Least significant word
@@ -3970,8 +3987,27 @@ arc_print_operand (FILE *file, rtx x, int code)
output_operand_lossage ("invalid operand to %%R code");
return;
case 'S' :
- /* FIXME: remove %S option. */
- break;
+ if (GET_CODE (x) == SYMBOL_REF
+ && arc_is_jli_call_p (x))
+ {
+ if (SYMBOL_REF_DECL (x))
+ {
+ tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
+ ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
+ : NULL_TREE);
+ if (lookup_attribute ("jli_fixed", attrs))
+ {
+ fprintf (file, "%ld\t; @",
+ TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
+ assemble_name (file, XSTR (x, 0));
+ return;
+ }
+ }
+ fprintf (file, "@__jli.");
+ assemble_name (file, XSTR (x, 0));
+ return;
+ }
+ break;
case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
if (CONSTANT_P (x))
{
@@ -5084,6 +5120,36 @@ static void arc_file_start (void)
fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
}
+/* Implement `TARGET_ASM_FILE_END'. */
+/* Outputs to the stdio stream FILE jli related text. */
+
+void arc_file_end (void)
+{
+ arc_jli_section *sec = arc_jli_sections;
+
+ while (sec != NULL)
+ {
+ fprintf (asm_out_file, "\n");
+ fprintf (asm_out_file, "# JLI entry for function ");
+ assemble_name (asm_out_file, sec->name);
+ fprintf (asm_out_file, "\n\t.section .jlitab, \"axG\", @progbits, "
+ ".jlitab.");
+ assemble_name (asm_out_file, sec->name);
+ fprintf (asm_out_file,", comdat\n");
+
+ fprintf (asm_out_file, "\t.align\t4\n");
+ fprintf (asm_out_file, "__jli.");
+ assemble_name (asm_out_file, sec->name);
+ fprintf (asm_out_file, ":\n\t.weak __jli.");
+ assemble_name (asm_out_file, sec->name);
+ fprintf (asm_out_file, "\n\tb\t@");
+ assemble_name (asm_out_file, sec->name);
+ fprintf (asm_out_file, "\n");
+ sec = sec->next;
+ }
+ file_end_indicate_exec_stack ();
+}
+
/* Cost functions. */
/* Compute a (partial) cost for rtx X. Return true if the complete
@@ -6866,13 +6932,25 @@ check_if_valid_sleep_operand (rtx *operands, int opno)
/* Return true if it is ok to make a tail-call to DECL. */
static bool
-arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
+arc_function_ok_for_sibcall (tree decl,
tree exp ATTRIBUTE_UNUSED)
{
+ tree attrs = NULL_TREE;
+
/* Never tailcall from an ISR routine - it needs a special exit sequence. */
if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
return false;
+ if (decl)
+ {
+ attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+
+ if (lookup_attribute ("jli_always", attrs))
+ return false;
+ if (lookup_attribute ("jli_fixed", attrs))
+ return false;
+ }
+
/* Everything else is ok. */
return true;
}
@@ -7577,6 +7655,73 @@ arc_reorg_loops (void)
reorg_loops (true, &arc_doloop_hooks);
}
+/* Add the given function declaration to emit code in JLI section. */
+
+static void
+arc_add_jli_section (rtx pat)
+{
+ const char *name;
+ tree attrs;
+ arc_jli_section *sec = arc_jli_sections, *new_section;
+ tree decl = SYMBOL_REF_DECL (pat);
+
+ if (!pat)
+ return;
+
+ if (decl)
+ {
+ /* For fixed locations do not generate the jli table entry. It
+ should be provided by the user as an asm file. */
+ attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+ if (lookup_attribute ("jli_fixed", attrs))
+ return;
+ }
+
+ name = XSTR (pat, 0);
+
+ /* Don't insert the same symbol twice. */
+ while (sec != NULL)
+ {
+ if(strcmp (name, sec->name) == 0)
+ return;
+ sec = sec->next;
+ }
+
+ /* New name, insert it. */
+ new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
+ gcc_assert (new_section != NULL);
+ new_section->name = name;
+ new_section->next = arc_jli_sections;
+ arc_jli_sections = new_section;
+}
+
+/* Scan all calls and add symbols to be emitted in the jli section if
+ needed. */
+
+static void
+jli_call_scan (void)
+{
+ rtx_insn *insn;
+
+ for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ {
+ if (!CALL_P (insn))
+ continue;
+
+ rtx pat = PATTERN (insn);
+ if (GET_CODE (pat) == COND_EXEC)
+ pat = COND_EXEC_CODE (pat);
+ pat = XVECEXP (pat, 0, 0);
+ if (GET_CODE (pat) == SET)
+ pat = SET_SRC (pat);
+
+ pat = XEXP (XEXP (pat, 0), 0);
+ if (GET_CODE (pat) == SYMBOL_REF
+ && arc_is_jli_call_p (pat))
+ arc_add_jli_section (pat);
+ }
+}
+
static int arc_reorg_in_progress = 0;
/* ARC's machince specific reorg function. */
@@ -7601,6 +7746,7 @@ arc_reorg (void)
arc_reorg_loops ();
workaround_arc_anomaly ();
+ jli_call_scan ();
/* FIXME: should anticipate ccfsm action, generate special patterns for
to-be-deleted branches that have no delay slot and have at least the
@@ -8279,11 +8425,11 @@ arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
/* Try to emit a 16 bit opcode with long immediate. */
ret = 6;
if (short_p && match)
- ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
+ ADDSI_OUTPUT1 ("add%? %0,%1,%2");
/* We have to use a 32 bit opcode, and with a long immediate. */
ret = 8;
- ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
+ ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
}
/* Emit code for an commutative_cond_exec instruction with OPERANDS.
@@ -10822,6 +10968,68 @@ arc_builtin_setjmp_frame_value (void)
return gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
}
+/* Return nonzero if a jli call should be generated for a call from
+ the current function to DECL. */
+
+bool
+arc_is_jli_call_p (rtx pat)
+{
+ tree attrs;
+ tree decl = SYMBOL_REF_DECL (pat);
+
+ /* If it is not a well defined public function then return false. */
+ if (!decl || !SYMBOL_REF_FUNCTION_P (pat) || !TREE_PUBLIC (decl))
+ return false;
+
+ attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+ if (lookup_attribute ("jli_always", attrs))
+ return true;
+
+ if (lookup_attribute ("jli_fixed", attrs))
+ return true;
+
+ return TARGET_JLI_ALWAYS;
+}
+
+/* Handle and "jli" attribute; arguments as in struct
+ attribute_spec.handler. */
+
+static tree
+arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
+ tree name, tree args, int,
+ bool *no_add_attrs)
+{
+ if (!TARGET_V2)
+ {
+ warning (OPT_Wattributes,
+ "%qE attribute only valid for ARCv2 architecture",
+ name);
+ *no_add_attrs = true;
+ }
+
+ if (args == NULL_TREE)
+ {
+ warning (OPT_Wattributes,
+ "argument of %qE attribute is missing",
+ name);
+ *no_add_attrs = true;
+ }
+ else
+ {
+ if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
+ TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
+ tree arg = TREE_VALUE (args);
+ if (TREE_CODE (arg) != INTEGER_CST)
+ {
+ warning (0, "%qE attribute allows only an integer constant argument",
+ name);
+ *no_add_attrs = true;
+ }
+ /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
+ }
+ return NULL_TREE;
+}
+
/* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
anchors for small data: the GP register acts as an anchor in that
case. We also don't want to use them for PC-relative accesses,
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 10b027a..233e6f5 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -641,7 +641,7 @@
mov%? %0,%1
mov%? %0,%1
mov%? %0,%1
- mov%? %0,%S1
+ mov%? %0,%1
ldb%? %0,%1%&
stb%? %1,%0%&
ldb%? %0,%1%&
@@ -682,9 +682,9 @@
mov%? %0,%1
mov%? %0,%1
mov%? %0,%1
- mov%? %0,%S1%&
- mov%? %0,%S1
- mov%? %0,%S1
+ mov%? %0,%1%&
+ mov%? %0,%1
+ mov%? %0,%1
ld%_%? %0,%1%&
st%_%? %1,%0%&
xld%_%U1 %0,%1
@@ -692,8 +692,8 @@
xst%_%U0 %1,%0
st%_%U0%V0 %1,%0
st%_%U0%V0 %1,%0
- st%_%U0%V0 %S1,%0
- st%_%U0%V0 %S1,%0"
+ st%_%U0%V0 %1,%0
+ st%_%U0%V0 %1,%0"
[(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store")
(set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,maybe_limm,false,true,true,false,false,false,false,false,false,false")
(set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no")
@@ -738,7 +738,7 @@
movh.cl %0,%L1>>16 ;9
* return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;10\" : \"movbi.cl %0,%L1 >> 24,24,8;10\";
mov%? %0,%1 ;11
- add %0,%S1 ;12
+ add %0,%1 ;12
add %0,pcl,%1@pcl ;13
mov%? %0,%1 ;14
mov%? %0,%1 ;15
@@ -799,7 +799,7 @@
(set (match_operand:SI 0 "register_operand" "=w,w,w")
(match_dup 1))]
""
- "mov%?.f %0,%S1"
+ "mov%?.f %0,%1"
; splitting to 'tst' allows short insns and combination into brcc.
"reload_completed && operands_match_p (operands[0], operands[1])"
[(set (match_dup 2) (match_dup 3))]
@@ -1287,7 +1287,7 @@
(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
(plus:SI (match_dup 1) (match_dup 2)))]
""
- "ldb.a%V4 %3,[%0,%S2]"
+ "ldb.a%V4 %3,[%0,%2]"
[(set_attr "type" "load,load")
(set_attr "length" "4,8")])
@@ -1299,7 +1299,7 @@
(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
(plus:SI (match_dup 1) (match_dup 2)))]
""
- "ldb.a%V4 %3,[%0,%S2]"
+ "ldb.a%V4 %3,[%0,%2]"
[(set_attr "type" "load,load")
(set_attr "length" "4,8")])
@@ -1311,7 +1311,7 @@
(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
(plus:SI (match_dup 1) (match_dup 2)))]
""
- "ldb.x.a%V4 %3,[%0,%S2]"
+ "ldb.x.a%V4 %3,[%0,%2]"
[(set_attr "type" "load,load")
(set_attr "length" "4,8")])
@@ -1337,7 +1337,7 @@
(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
(plus:SI (match_dup 1) (match_dup 2)))]
""
- "ld%_.a%V4 %3,[%0,%S2]"
+ "ld%_.a%V4 %3,[%0,%2]"
[(set_attr "type" "load,load")
(set_attr "length" "4,8")])
@@ -1349,7 +1349,7 @@
(set (match_operand:SI 0 "dest_reg_operand" "=r,r")
(plus:SI (match_dup 1) (match_dup 2)))]
""
- "ld%_.a%V4 %3,[%0,%S2]"
+ "ld%_.a%V4 %3,[%0,%2]"
[(set_attr "type" "load,load")
(set_attr "length" "4,8")])
@@ -1362,7 +1362,7 @@
(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
(plus:SI (match_dup 1) (match_dup 2)))]
""
- "ld%_.x.a%V4 %3,[%0,%S2]"
+ "ld%_.x.a%V4 %3,[%0,%2]"
[(set_attr "type" "load,load")
(set_attr "length" "4,8")])
@@ -1387,7 +1387,7 @@
(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
(plus:SI (match_dup 1) (match_dup 2)))]
""
- "ld.a%V4 %3,[%0,%S2]"
+ "ld.a%V4 %3,[%0,%2]"
[(set_attr "type" "load,load")
(set_attr "length" "4,8")])
@@ -1411,7 +1411,7 @@
(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
(plus:SI (match_dup 1) (match_dup 2)))]
""
- "ld.a%V4 %3,[%0,%S2]"
+ "ld.a%V4 %3,[%0,%2]"
[(set_attr "type" "load,load")
(set_attr "length" "4,8")])
@@ -1479,7 +1479,7 @@
&& rtx_equal_p (operands[1], constm1_rtx)
&& GET_CODE (operands[3]) == LTU)
return "sbc.cs %0,%0,%0";
- return "mov.%d3 %0,%S1";
+ return "mov.%d3 %0,%1";
}
[(set_attr "type" "cmove,cmove")
(set_attr "length" "4,8")])
@@ -3144,7 +3144,7 @@
"@
bset%? %0,%1,%2 ;;peep2, constr 1
bset %0,%1,%2 ;;peep2, constr 2
- bset %0,%S1,%2 ;;peep2, constr 3"
+ bset %0,%1,%2 ;;peep2, constr 3"
[(set_attr "length" "4,4,8")
(set_attr "predicable" "yes,no,no")
(set_attr "cond" "canuse,nocond,nocond")]
@@ -3160,7 +3160,7 @@
"@
bxor%? %0,%1,%2
bxor %0,%1,%2
- bxor %0,%S1,%2"
+ bxor %0,%1,%2"
[(set_attr "length" "4,4,8")
(set_attr "predicable" "yes,no,no")
(set_attr "cond" "canuse,nocond,nocond")]
@@ -3176,7 +3176,7 @@
"@
bclr%? %0,%1,%2
bclr %0,%1,%2
- bclr %0,%S1,%2"
+ bclr %0,%1,%2"
[(set_attr "length" "4,4,8")
(set_attr "predicable" "yes,no,no")
(set_attr "cond" "canuse,nocond,nocond")]
@@ -3192,9 +3192,9 @@
(const_int -1))))]
""
"@
- bmsk%? %0,%S1,%2
+ bmsk%? %0,%1,%2
bmsk %0,%1,%2
- bmsk %0,%S1,%2"
+ bmsk %0,%1,%2"
[(set_attr "length" "4,4,8")
(set_attr "predicable" "yes,no,no")
(set_attr "cond" "canuse,nocond,nocond")]
@@ -3306,10 +3306,10 @@
bic%? %0, %2, %1%& ;;constraint 0
bic%? %0,%2,%1 ;;constraint 1
bic %0,%2,%1 ;;constraint 2, FIXME: will it ever get generated ???
- bic%? %0,%2,%S1 ;;constraint 3, FIXME: will it ever get generated ???
+ bic%? %0,%2,%1 ;;constraint 3, FIXME: will it ever get generated ???
bic %0,%2,%1 ;;constraint 4
- bic %0,%2,%S1 ;;constraint 5, FIXME: will it ever get generated ???
- bic %0,%S2,%1 ;;constraint 6"
+ bic %0,%2,%1 ;;constraint 5, FIXME: will it ever get generated ???
+ bic %0,%2,%1 ;;constraint 6"
[(set_attr "length" "*,4,4,8,4,8,8")
(set_attr "iscompact" "maybe, false, false, false, false, false, false")
(set_attr "predicable" "no,yes,no,yes,no,no,no")
@@ -3640,7 +3640,7 @@
(compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq,Rcqq, h, c,Rcqq, c")
(match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI, Cal,Cal")))]
""
- "cmp%? %0,%S1%&"
+ "cmp%? %0,%1%&"
[(set_attr "type" "compare")
(set_attr "iscompact" "true,true,true,false,true_limm,false")
(set_attr "cond" "set")
@@ -3747,7 +3747,7 @@
* current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
* current_insn_predicate = 0; return \"mov%?.ne %0,%1\";
mov.ne %0,%1
- mov.ne %0,%S1"
+ mov.ne %0,%1"
[(set_attr "type" "cmove")
(set_attr "iscompact" "true,true,true_limm,false,false")
(set_attr "length" "2,2,6,4,8")
@@ -3760,7 +3760,7 @@
(set (match_operand:SI 0 "dest_reg_operand" "=w,w")
(match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))]
""
- "mov.%d3 %0,%S1"
+ "mov.%d3 %0,%1"
[(set_attr "type" "cmove")
(set_attr "length" "4,8")])
@@ -4228,13 +4228,12 @@
}
")
-
; Rcq, which is used in alternative 0, checks for conditional execution.
; At instruction output time, if it doesn't match and we end up with
; alternative 1 ("q"), that means that we can't use the short form.
(define_insn "*call_i"
[(call (mem:SI (match_operand:SI 0
- "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
+ "call_address_operand" "Rcq,q,c,Cji,Cbp,Cbr,L,I,Cal"))
(match_operand 1 "" ""))
(clobber (reg:SI 31))]
""
@@ -4242,15 +4241,16 @@
jl%!%* [%0]%&
jl%!%* [%0]%&
jl%!%* [%0]
+ jli_s %S0
bl%!%* %P0
bl%!%* %P0
- jl%!%* %S0
- jl%* %S0
- jl%! %S0"
- [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
- (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
- (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
- (set_attr "length" "*,*,4,4,4,4,4,8")])
+ jl%!%* %0
+ jl%* %0
+ jl%! %0"
+ [(set_attr "type" "call,call,call,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
+ (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*")
+ (set_attr "predicable" "no,no,yes,no,yes,no,yes,no,yes")
+ (set_attr "length" "*,*,4,2,4,4,4,4,8")])
(define_expand "call_value"
;; operand 2 is stack_size_rtx
@@ -4272,14 +4272,13 @@
XEXP (operands[1], 0) = force_reg (Pmode, callee);
}")
-
; Rcq, which is used in alternative 0, checks for conditional execution.
; At instruction output time, if it doesn't match and we end up with
; alternative 1 ("q"), that means that we can't use the short form.
(define_insn "*call_value_i"
- [(set (match_operand 0 "dest_reg_operand" "=Rcq,q,w, w, w,w,w, w")
+ [(set (match_operand 0 "dest_reg_operand" "=Rcq,q,w, w, w, w,w,w, w")
(call (mem:SI (match_operand:SI 1
- "call_address_operand" "Rcq,q,c,Cbp,Cbr,L,I,Cal"))
+ "call_address_operand" "Rcq,q,c,Cji,Cbp,Cbr,L,I,Cal"))
(match_operand 2 "" "")))
(clobber (reg:SI 31))]
""
@@ -4287,15 +4286,16 @@
jl%!%* [%1]%&
jl%!%* [%1]%&
jl%!%* [%1]
+ jli_s %S1
bl%!%* %P1;1
bl%!%* %P1;1
- jl%!%* %S1
- jl%* %S1
- jl%! %S1"
- [(set_attr "type" "call,call,call,call,call,call,call,call_no_delay_slot")
- (set_attr "iscompact" "maybe,false,*,*,*,*,*,*")
- (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes")
- (set_attr "length" "*,*,4,4,4,4,4,8")])
+ jl%!%* %1
+ jl%* %1
+ jl%! %1"
+ [(set_attr "type" "call,call,call,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
+ (set_attr "iscompact" "maybe,false,*,true,*,*,*,*,*")
+ (set_attr "predicable" "no,no,yes,no,yes,no,yes,no,yes")
+ (set_attr "length" "*,*,4,2,4,4,4,4,8")])
; There is a bl_s instruction (16 bit opcode branch-and-link), but we can't
; use it for lack of inter-procedural branch shortening.
@@ -4467,7 +4467,7 @@
"TARGET_NORM"
"@
norm \t%0, %1
- norm \t%0, %S1"
+ norm \t%0, %1"
[(set_attr "length" "4,8")
(set_attr "type" "two_cycle_core,two_cycle_core")])
@@ -4479,7 +4479,7 @@
"TARGET_NORM"
"@
norm.f\t%0, %1
- norm.f\t%0, %S1"
+ norm.f\t%0, %1"
[(set_attr "length" "4,8")
(set_attr "type" "two_cycle_core,two_cycle_core")])
@@ -4499,7 +4499,7 @@
"TARGET_NORM"
"@
norm%_ \t%0, %1
- norm%_ \t%0, %S1"
+ norm%_ \t%0, %1"
[(set_attr "length" "4,8")
(set_attr "type" "two_cycle_core,two_cycle_core")])
@@ -4588,7 +4588,7 @@
"TARGET_SWAP"
"@
swap \t%0, %1
- swap \t%0, %S1
+ swap \t%0, %1
swap \t%0, %1"
[(set_attr "length" "4,8,4")
(set_attr "type" "two_cycle_core,two_cycle_core,two_cycle_core")])
@@ -4601,8 +4601,8 @@
"TARGET_ARC700 || TARGET_EA_SET"
"@
divaw \t%0, %1, %2
- divaw \t%0, %S1, %2
- divaw \t%0, %1, %S2"
+ divaw \t%0, %1, %2
+ divaw \t%0, %1, %2"
[(set_attr "length" "4,8,8")
(set_attr "type" "divaw,divaw,divaw")])
@@ -4613,7 +4613,7 @@
"@
flag%? %0
flag %0
- flag%? %S0"
+ flag%? %0"
[(set_attr "length" "4,4,8")
(set_attr "type" "misc,misc,misc")
(set_attr "predicable" "yes,no,yes")
@@ -4707,7 +4707,7 @@
(match_operand:SI 1 "general_operand" "Ir,I,HCal,r")]
VUNSPEC_ARC_SR)]
""
- "sr\t%S0, [%1]"
+ "sr\t%0, [%1]"
[(set_attr "length" "8,4,8,4")
(set_attr "type" "sr,sr,sr,sr")])
@@ -5283,7 +5283,7 @@
;; ??? Should this use arc_output_libcall and set is_sfunc?
(define_insn "*millicode_thunk_st"
[(match_parallel 0 "millicode_store_operation"
- [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
+ [(set (mem:SI (reg:SI SP_REG)) (reg:SI 13))])]
""
{
output_asm_insn ("bl%* __st_r13_to_%0",
@@ -5295,7 +5295,7 @@
(define_insn "*millicode_thunk_ld"
[(match_parallel 0 "millicode_load_clob_operation"
- [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
+ [(set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
""
{
output_asm_insn ("bl%* __ld_r13_to_%0",
@@ -5308,9 +5308,9 @@
; the sibthunk restores blink, so we use the return rtx.
(define_insn "*millicode_sibthunk_ld"
[(match_parallel 0 "millicode_load_operation"
- [(return)
- (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
- (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
+ [(return)
+ (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (reg:SI 12)))
+ (set (reg:SI 13) (mem:SI (reg:SI SP_REG)))])]
""
{
output_asm_insn ("b%* __ld_r13_to_%0_ret",
@@ -5629,7 +5629,7 @@
"@
kflag%? %0
kflag %0
- kflag%? %S0"
+ kflag%? %0"
[(set_attr "length" "4,4,8")
(set_attr "type" "misc,misc,misc")
(set_attr "predicable" "yes,no,yes")
@@ -5651,7 +5651,7 @@
"TARGET_NORM && TARGET_V2"
"@
ffs \t%0, %1
- ffs \t%0, %S1"
+ ffs \t%0, %1"
[(set_attr "length" "4,8")
(set_attr "type" "two_cycle_core,two_cycle_core")])
@@ -5664,7 +5664,7 @@
"TARGET_NORM && TARGET_V2"
"@
ffs.f\t%0, %1
- ffs.f\t%0, %S1"
+ ffs.f\t%0, %1"
[(set_attr "length" "4,8")
(set_attr "type" "two_cycle_core,two_cycle_core")])
@@ -5691,7 +5691,7 @@
"TARGET_NORM && TARGET_V2"
"@
fls \t%0, %1
- fls \t%0, %S1"
+ fls \t%0, %1"
[(set_attr "length" "4,8")
(set_attr "type" "two_cycle_core,two_cycle_core")])
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 593bd2d..5f10c0e 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -53,6 +53,10 @@ mARC700
Target Report
Same as -mA7.
+mjli-always
+Target Report Mask(JLI_ALWAYS)
+Force all calls to be made via a jli instruction.
+
mmpy-option=
Target RejectNegative Joined Enum(arc_mpy) Var(arc_mpy_option) Init(DEFAULT_arc_mpy_option)
-mmpy-option=MPY Compile ARCv2 code with a multiplier design option.
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index 7c34ffd..565d860 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -401,6 +401,12 @@
(match_test "arc_is_shortcall_p (op)"))
(match_code "label_ref")))
+(define_constraint "Cji"
+ "JLI call"
+ (and (match_code "symbol_ref")
+ (match_test "TARGET_CODE_DENSITY")
+ (match_test "arc_is_jli_call_p (op)")))
+
(define_constraint "Cpc"
"pc-relative constant"
(match_test "arc_legitimate_pic_addr_p (op)"))
diff --git a/gcc/config/arc/elf.h b/gcc/config/arc/elf.h
index 5abafca..3bb9cb0 100644
--- a/gcc/config/arc/elf.h
+++ b/gcc/config/arc/elf.h
@@ -66,3 +66,6 @@ along with GCC; see the file COPYING3. If not see
/* Pre/post modify with register displacement are default. */
#undef TARGET_AUTO_MODIFY_REG_DEFAULT
#define TARGET_AUTO_MODIFY_REG_DEFAULT 1
+
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END arc_file_end
diff --git a/gcc/config/arc/fpx.md b/gcc/config/arc/fpx.md
index db7b642..8f65df1 100644
--- a/gcc/config/arc/fpx.md
+++ b/gcc/config/arc/fpx.md
@@ -59,9 +59,9 @@
"@
fadd %0,%1,%2
fadd %0,%1,%2
- fadd %0,%S1,%2
- fadd %0,%1,%S2
- fadd%? %0,%1,%S2"
+ fadd %0,%1,%2
+ fadd %0,%1,%2
+ fadd%? %0,%1,%2"
[(set_attr "type" "spfp")
(set_attr "length" "4,4,8,8,8")])
@@ -74,9 +74,9 @@
"@
fsub %0,%1,%2
fsub %0,%1,%2
- fsub %0,%S1,%2
- fsub %0,%1,%S2
- fsub%? %0,%1,%S2"
+ fsub %0,%1,%2
+ fsub %0,%1,%2
+ fsub%? %0,%1,%2"
[(set_attr "type" "spfp")
(set_attr "length" "4,4,8,8,8")])
@@ -89,9 +89,9 @@
"@
fmul %0,%1,%2
fmul %0,%1,%2
- fmul %0,%S1,%2
- fmul %0,%1,%S2
- fmul%? %0,%1,%S2"
+ fmul %0,%1,%2
+ fmul %0,%1,%2
+ fmul%? %0,%1,%2"
[(set_attr "type" "spfp")
(set_attr "length" "4,4,8,8,8")])
diff --git a/gcc/config/arc/linux.h b/gcc/config/arc/linux.h
index 633ae90..3850833 100644
--- a/gcc/config/arc/linux.h
+++ b/gcc/config/arc/linux.h
@@ -61,6 +61,7 @@ along with GCC; see the file COPYING3. If not see
%{shared:-lc} \
%{!shared:%{profile:-lc_p}%{!profile:-lc}}"
+#undef TARGET_ASM_FILE_END
#define TARGET_ASM_FILE_END file_end_indicate_exec_stack
/* No SDATA default for linux. */
diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md
index e742638..8885a6a 100644
--- a/gcc/config/arc/simdext.md
+++ b/gcc/config/arc/simdext.md
@@ -1190,7 +1190,7 @@
(define_insn "vendrec_insn"
[(unspec_volatile [(match_operand:SI 0 "nonmemory_operand" "r")] UNSPEC_ARC_SIMD_VENDREC)]
"TARGET_SIMD_SET"
- "vendrec %S0"
+ "vendrec %0"
[(set_attr "type" "simd_vcontrol")
(set_attr "length" "4")
(set_attr "cond" "nocond")])