This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello! I'm new to GCC internals, but I'm using GCC for couple of years. Yesterday I found that GCC does not support calling SWI routines from C/C++ code. For example, in other ARM-targeted compiliers developer can use such syntax for function prototype: In ARM IAR: #pragma swi_number=0x15 int some_call(int, int); In RVDS: __swi(0x15) int some_call(int, int); And then just call function as usual: a = some_call(5, 8); GCC lacks this feauture, so I've decided to go on Free Software way - if your need something, implement it yourself =) I can't write any testsuite, because I don't know how to do it, sorry. I tested some programs written for IAR, they compiled and launched successfully. I've also tested some programs with functions that don't use this attribute - they was unaffected by this patch. So I decided to send it to this mailing list. Changelog and patch included in attachment. I tested cross-compiling, host=i686-pc-linux-gnu and host=x86_64-pc-linux-gnu, target=arm-linux-gnueabi. Works stable and fine. Barracuda
diff -aur sources/gcc-4.5.1/gcc/config/arm//arm.c gcc-4.5.1/gcc/config/arm//arm.c --- sources/gcc-4.5.1/gcc/config/arm//arm.c 2010-07-12 20:05:41.000000000 +0600 +++ gcc-4.5.1/gcc/config/arm//arm.c 2012-02-21 04:24:13.295235261 +0600 @@ -225,6 +225,7 @@ static void arm_trampoline_init (rtx, tree, rtx); static rtx arm_trampoline_adjust_address (rtx); +static tree arm_handle_swi_attribute (tree *, tree, tree, int, bool *); /* Table of machine attributes. */ static const struct attribute_spec arm_attribute_table[] = @@ -243,6 +246,7 @@ { "isr", 0, 1, false, false, false, arm_handle_isr_attribute }, { "interrupt", 0, 1, false, false, false, arm_handle_isr_attribute }, { "naked", 0, 0, true, false, false, arm_handle_fndecl_attribute }, + { "swi", 1, 1, false, false, false, arm_handle_swi_attribute }, #ifdef ARM_PE /* ARM/PE has three new attributes: interfacearm - ? @@ -4595,6 +4601,47 @@ return NULL_TREE; } +static tree +arm_handle_swi_attribute (tree *node, tree name, tree args, int flags, + bool *no_add_attrs) +{ + if (DECL_P (*node)) + { + if (TREE_CODE (*node) != FUNCTION_DECL) + { + warning (OPT_Wattributes, "%qE attribute only applies to functions", + name); + *no_add_attrs = true; + } else { + tree cst = TREE_VALUE (args); + if (TREE_CODE (cst) != INTEGER_CST) + { + error ("%qE attribute requires an integer constant argument", + name); + *no_add_attrs = true; + } + else if (TARGET_ARM && (compare_tree_int (cst, 0xFFFFFF) > 0)) + { + error ("argument to %qE attribute larger than 0xFFFFFF", + name); + *no_add_attrs = true; + } + else if (TARGET_THUMB && (compare_tree_int (cst, 0xFF) > 0)) + { + error ("argument to %qE attribute larger than 0xFF", + name); + *no_add_attrs = true; + } + } + } else { + warning (OPT_Wattributes, + "%qE attribute can be applied only to function prototype"); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle a "pcs" attribute; arguments as in struct attribute_spec.handler. */ static tree @@ -4768,6 +4821,52 @@ return TARGET_LONG_CALLS; } +bool +arm_is_swicall (tree decl) +{ + tree attrs; + tree a; + + if (!decl) + { + return false; + } + + attrs = DECL_ATTRIBUTES ( decl); + a = lookup_attribute ("swi", attrs); + if (a == NULL_TREE) + { + return false; + } + + return true; +} + +const char * +output_swicall (tree decl) +{ + tree attrs; + tree a; + tree cst; + int value; + char *buf = ggc_alloc_cleared (32); + + attrs = DECL_ATTRIBUTES (decl); + a = lookup_attribute ("swi", attrs); + if (TREE_VALUE (a) == NULL_TREE) + return "ERROR"; + + cst = TREE_VALUE (TREE_VALUE (a)); + if (TREE_CODE (cst) != INTEGER_CST) + return "ERROR1"; + + value = TREE_INT_CST_LOW (cst); + + snprintf (buf, 32, "swi%%?\t%d", value); + + return buf; +} + /* Return nonzero if it is ok to make a tail-call to DECL. */ static bool arm_function_ok_for_sibcall (tree decl, tree exp) diff -aur sources/gcc-4.5.1/gcc/config/arm//arm.md gcc-4.5.1/gcc/config/arm//arm.md --- sources/gcc-4.5.1/gcc/config/arm//arm.md 2010-07-31 04:35:40.000000000 +0600 +++ gcc-4.5.1/gcc/config/arm//arm.md 2012-02-21 04:20:46.846224042 +0600 @@ -8646,7 +8646,11 @@ && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" "* { - return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\"; + bool is_swi = arm_is_swicall (SYMBOL_REF_DECL (operands[1])); + if (is_swi) + return output_swicall (SYMBOL_REF_DECL (operands[1])); + else + return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\"; }" [(set_attr "type" "call")] ) @@ -8673,7 +8678,14 @@ "TARGET_THUMB && GET_CODE (operands[1]) == SYMBOL_REF && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" - "bl\\t%a1" + "* + { + bool is_swi = arm_is_swicall (SYMBOL_REF_DECL (operands[1])); + if (is_swi) + return output_swicall (SYMBOL_REF_DECL (operands[1])); + else + return \"bl\\t%a1\"; + }" [(set_attr "length" "4") (set_attr "type" "call")] ) diff -aur sources/gcc-4.5.1/gcc/config/arm//arm-protos.h gcc-4.5.1/gcc/config/arm//arm-protos.h --- sources/gcc-4.5.1/gcc/config/arm//arm-protos.h 2010-07-05 18:45:19.000000000 +0600 +++ gcc-4.5.1/gcc/config/arm//arm-protos.h 2012-02-21 04:04:38.185415081 +0600 @@ -120,6 +120,7 @@ extern void arm_emit_call_insn (rtx, rtx); extern const char *output_call (rtx *); extern const char *output_call_mem (rtx *); +extern const char *output_swicall (tree decl); void arm_emit_movpair (rtx, rtx); extern const char *output_mov_long_double_fpa_from_arm (rtx *); extern const char *output_mov_long_double_arm_from_fpa (rtx *); @@ -141,6 +144,7 @@ extern void arm_final_prescan_insn (rtx); extern int arm_debugger_arg_offset (int, rtx); extern bool arm_is_long_call_p (tree); +extern bool arm_is_swicall (tree); extern int arm_emit_vector_const (FILE *, rtx); extern void arm_emit_fp16_const (rtx c); extern const char * arm_output_load_gr (rtx *);
Attachment:
Chlog.txt
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |