From 7778a1ad1fa10f5202ec65838d1d91a0261ce95c Mon Sep 17 00:00:00 2001 From: Claudiu Zissulescu Date: Fri, 26 Jan 2018 12:33:42 +0100 Subject: [PATCH] [ARC] Add SJLI support. gcc/ 2018-01-26 Claudiu Zissulescu * 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 --- gcc/ChangeLog | 13 +++ gcc/config/arc/arc-protos.h | 1 + gcc/config/arc/arc.c | 163 +++++++++++++++++++++++++--------- gcc/config/arc/arc.md | 32 +++---- gcc/config/arc/constraints.md | 7 ++ gcc/doc/extend.texi | 6 ++ 6 files changed, 167 insertions(+), 55 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 61a85f8c9d7..8782ff8b17a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2018-01-26 Claudiu Zissulescu + + * 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 John Eric Martin diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h index 7274fe0e4a0..76b82bfb517 100644 --- a/gcc/config/arc/arc-protos.h +++ b/gcc/config/arc/arc-protos.h @@ -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); diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 78cf323a036..1ad0bf601f6 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -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, diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md index 233e6f5379e..172fd115d25 100644 --- a/gcc/config/arc/arc.md +++ b/gcc/config/arc/arc.md @@ -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. diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md index 565d8608e85..7249107d988 100644 --- a/gcc/config/arc/constraints.md +++ b/gcc/config/arc/constraints.md @@ -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)")) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 478894be0ea..a4b21e6c67a 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 -- 2.30.2