Commit 7778a1ad by Claudiu Zissulescu Committed by Claudiu Zissulescu

[ARC] Add SJLI support.

gcc/
2018-01-26  Claudiu Zissulescu  <claziss@synopsys.com>

        * config/arc/arc-protos.h: Add arc_is_secure_call_p proto.
        * config/arc/arc.c (arc_handle_secure_attribute): New function.
        (arc_attribute_table): Add 'secure_call' attribute.
        (arc_print_operand): Print secure call operand.
        (arc_function_ok_for_sibcall): Don't optimize tail calls when
        secure.
        (arc_is_secure_call_p): New function.
        * config/arc/arc.md (call_i): Add support for sjli instruction.
        (call_value_i): Likewise.
        * config/arc/constraints.md (Csc): New constraint.

From-SVN: r257082
parent 6b55f8c9
2018-01-26 Claudiu Zissulescu <claziss@synopsys.com>
* config/arc/arc-protos.h: Add arc_is_secure_call_p proto.
* config/arc/arc.c (arc_handle_secure_attribute): New function.
(arc_attribute_table): Add 'secure_call' attribute.
(arc_print_operand): Print secure call operand.
(arc_function_ok_for_sibcall): Don't optimize tail calls when
secure.
(arc_is_secure_call_p): New function. * config/arc/arc.md
(call_i): Add support for sjli instruction.
(call_value_i): Likewise.
* config/arc/constraints.md (Csc): New constraint.
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.
......
......@@ -118,3 +118,4 @@ 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);
extern bool arc_is_secure_call_p (rtx);
......@@ -226,6 +226,7 @@ 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 *);
static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
/* Initialized arc_attribute_table to NULL since arc doesnot have any
......@@ -257,6 +258,9 @@ const struct attribute_spec arc_attribute_table[] =
table is given as input parameter. */
{ "jli_fixed", 1, 1, false, true, true, arc_handle_jli_attribute,
NULL },
/* Call a function using secure-mode. */
{ "secure_call", 1, 1, false, true, true, arc_handle_secure_attribute,
NULL },
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
static int arc_comp_type_attributes (const_tree, const_tree);
......@@ -3745,6 +3749,46 @@ arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
Pmode);
}
/* 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;
}
/* This is set briefly to 1 when we output a ".as" address modifer, and then
reset when we output the scaled address. */
static int output_scaled = 0;
......@@ -3772,6 +3816,7 @@ static int output_scaled = 0;
'D'
'R': Second word
'S': JLI instruction
'j': used by mov instruction to properly emit jli related labels.
'B': Branch comparison operand - suppress sda reference
'H': Most significant word
'L': Least significant word
......@@ -3986,6 +4031,7 @@ arc_print_operand (FILE *file, rtx x, int code)
else
output_operand_lossage ("invalid operand to %%R code");
return;
case 'j':
case 'S' :
if (GET_CODE (x) == SYMBOL_REF
&& arc_is_jli_call_p (x))
......@@ -3997,6 +4043,9 @@ arc_print_operand (FILE *file, rtx x, int code)
: NULL_TREE);
if (lookup_attribute ("jli_fixed", attrs))
{
/* No special treatment for jli_fixed functions. */
if (code == 'j')
break;
fprintf (file, "%ld\t; @",
TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
assemble_name (file, XSTR (x, 0));
......@@ -4005,6 +4054,22 @@ arc_print_operand (FILE *file, rtx x, int code)
}
fprintf (file, "@__jli.");
assemble_name (file, XSTR (x, 0));
if (code == 'j')
arc_add_jli_section (x);
return;
}
if (GET_CODE (x) == SYMBOL_REF
&& arc_is_secure_call_p (x))
{
/* No special treatment for secure functions. */
if (code == 'j' )
break;
tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
: NULL_TREE);
fprintf (file, "%ld\t; @",
TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
assemble_name (file, XSTR (x, 0));
return;
}
break;
......@@ -6949,6 +7014,8 @@ arc_function_ok_for_sibcall (tree decl,
return false;
if (lookup_attribute ("jli_fixed", attrs))
return false;
if (lookup_attribute ("secure_call", attrs))
return false;
}
/* Everything else is ok. */
......@@ -7655,46 +7722,6 @@ 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. */
......@@ -11030,6 +11057,62 @@ arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
return NULL_TREE;
}
/* Handle and "scure" attribute; arguments as in struct
attribute_spec.handler. */
static tree
arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED,
tree name, tree args, int,
bool *no_add_attrs)
{
if (!TARGET_EM)
{
warning (OPT_Wattributes,
"%qE attribute only valid for ARC EM 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;
}
}
return NULL_TREE;
}
/* Return nonzero if the symbol is a secure function. */
bool
arc_is_secure_call_p (rtx pat)
{
tree attrs;
tree decl = SYMBOL_REF_DECL (pat);
if (!decl)
return false;
attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
if (lookup_attribute ("secure_call", attrs))
return true;
return false;
}
/* 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,
......
......@@ -740,10 +740,10 @@
mov%? %0,%1 ;11
add %0,%1 ;12
add %0,pcl,%1@pcl ;13
mov%? %0,%1 ;14
mov%? %0,%1 ;15
mov%? %0,%1 ;16
ld%?%U1 %0,%1 ;17
mov%? %0,%j1 ;14
mov%? %0,%j1 ;15
mov%? %0,%j1 ;16
ld%? %0,%1 ;17
st%? %1,%0%& ;18
* return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
* return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\");
......@@ -4233,7 +4233,7 @@
; 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,Cji,Cbp,Cbr,L,I,Cal"))
"call_address_operand" "Rcq,q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
(match_operand 1 "" ""))
(clobber (reg:SI 31))]
""
......@@ -4242,15 +4242,16 @@
jl%!%* [%0]%&
jl%!%* [%0]
jli_s %S0
sjli %S0
bl%!%* %P0
bl%!%* %P0
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")])
[(set_attr "type" "call,call,call,call_no_delay_slot,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,no,yes,no,yes,no,yes")
(set_attr "length" "*,*,4,2,4,4,4,4,4,8")])
(define_expand "call_value"
;; operand 2 is stack_size_rtx
......@@ -4276,9 +4277,9 @@
; 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, w")
[(set (match_operand 0 "dest_reg_operand" "=Rcq,q,w, w, w, w, w,w,w, w")
(call (mem:SI (match_operand:SI 1
"call_address_operand" "Rcq,q,c,Cji,Cbp,Cbr,L,I,Cal"))
"call_address_operand" "Rcq,q,c,Cji,Csc,Cbp,Cbr,L,I,Cal"))
(match_operand 2 "" "")))
(clobber (reg:SI 31))]
""
......@@ -4287,15 +4288,16 @@
jl%!%* [%1]%&
jl%!%* [%1]
jli_s %S1
sjli %S1
bl%!%* %P1;1
bl%!%* %P1;1
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")])
[(set_attr "type" "call,call,call,call_no_delay_slot,call_no_delay_slot,call,call,call,call,call_no_delay_slot")
(set_attr "iscompact" "maybe,false,*,true,false,*,*,*,*,*")
(set_attr "predicable" "no,no,yes,no,no,yes,no,yes,no,yes")
(set_attr "length" "*,*,4,2,4,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.
......
......@@ -407,6 +407,13 @@
(match_test "TARGET_CODE_DENSITY")
(match_test "arc_is_jli_call_p (op)")))
(define_constraint "Csc"
"Secure call"
(and (match_code "symbol_ref")
(match_test "TARGET_CODE_DENSITY")
(match_test "TARGET_EM")
(match_test "arc_is_secure_call_p (op)")))
(define_constraint "Cpc"
"pc-relative constant"
(match_test "arc_legitimate_pic_addr_p (op)"))
......
......@@ -3775,6 +3775,12 @@ which are addressed using this instruction.
Identical like the above one, but the location of the function in the
@code{jli} table is known and given as an attribute parameter.
@item secure_call
@cindex @code{secure_call} function attribute, ARC
This attribute allows one to mark secure-code functions that are
callable from normal mode. The location of the secure call function
into the @code{sjli} table needs to be passed as argument.
@end table
@node ARM Function Attributes
......
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