Commit 9597375a by Oleg Endo

re PR target/50457 (SH2A atomic functions)

	PR target/50457
	* config/sh/sh.c (parse_validate_atomic_model_option): Handle name
	strings in sh_atomic_model.
	* config/sh/sh.h (TARGET_CPU_CPP_BUILTINS): Move macro implementation
	to ...
	* config/sh/sh-c.c (sh_cpu_cpp_builtins): ... this new function.
	Add __SH1__ and __SH2__ defines.  Add __SH_ATOMIC_MODEL_*__ define.
	* config/sh/sh-protos.h (sh_atomic_model): Add name and cdef_name
	variables.
	(sh_cpu_cpp_builtins): Declare new function.

	PR target/50457
	* config/sh/linux-atomic.S: Delete.
	* config/sh/linux-atomic.c: New.
	* config/sh/t-linux (LIB2ADD): Replace linux-atomic.S with
	linux-atomic.c.  Add cflags to disable warnings.

From-SVN: r192051
parent 846b158c
2012-10-03 Oleg Endo <olegendo@gcc.gnu.org>
PR target/50457
* config/sh/sh.c (parse_validate_atomic_model_option): Handle name
strings in sh_atomic_model.
* config/sh/sh.h (TARGET_CPU_CPP_BUILTINS): Move macro implementation
to ...
* config/sh/sh-c.c (sh_cpu_cpp_builtins): ... this new function.
Add __SH1__ and __SH2__ defines. Add __SH_ATOMIC_MODEL_*__ define.
* config/sh/sh-protos.h (sh_atomic_model): Add name and cdef_name
variables.
(sh_cpu_cpp_builtins): Declare new function.
2012-10-03 Dehao Chen <dehao@google.com> 2012-10-03 Dehao Chen <dehao@google.com>
PR middle-end/54782 PR middle-end/54782
......
...@@ -25,6 +25,9 @@ along with GCC; see the file COPYING3. If not see ...@@ -25,6 +25,9 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h" #include "tm.h"
#include "tree.h" #include "tree.h"
#include "tm_p.h" #include "tm_p.h"
#include "cpplib.h"
#include "c-family/c-common.h"
#include "target.h"
/* Handle machine specific pragmas to be semi-compatible with Renesas /* Handle machine specific pragmas to be semi-compatible with Renesas
compiler. */ compiler. */
...@@ -66,3 +69,79 @@ sh_pr_nosave_low_regs (struct cpp_reader *pfile ATTRIBUTE_UNUSED) ...@@ -66,3 +69,79 @@ sh_pr_nosave_low_regs (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
{ {
sh_add_function_attribute ("nosave_low_regs"); sh_add_function_attribute ("nosave_low_regs");
} }
#define builtin_define(TXT) cpp_define (pfile, TXT)
#define builtin_assert(TXT) cpp_assert (pfile, TXT)
/* Implement the TARGET_CPU_CPP_BUILTINS macro */
void
sh_cpu_cpp_builtins (cpp_reader* pfile)
{
builtin_define ("__sh__");
builtin_assert ("cpu=sh");
builtin_assert ("machine=sh");
switch ((int) sh_cpu)
{
case PROCESSOR_SH1:
builtin_define ("__sh1__");
builtin_define ("__SH1__");
break;
case PROCESSOR_SH2:
builtin_define ("__sh2__");
builtin_define ("__SH2__");
break;
case PROCESSOR_SH2E:
builtin_define ("__SH2E__");
break;
case PROCESSOR_SH2A:
builtin_define ("__SH2A__");
if (TARGET_SH2A_DOUBLE)
builtin_define (TARGET_FPU_SINGLE
? "__SH2A_SINGLE__" : "__SH2A_DOUBLE__");
else
builtin_define (TARGET_FPU_ANY
? "__SH2A_SINGLE_ONLY__" : "__SH2A_NOFPU__");
break;
case PROCESSOR_SH3:
builtin_define ("__sh3__");
builtin_define ("__SH3__");
if (TARGET_HARD_SH4)
builtin_define ("__SH4_NOFPU__");
break;
case PROCESSOR_SH3E:
builtin_define (TARGET_HARD_SH4 ? "__SH4_SINGLE_ONLY__" : "__SH3E__");
break;
case PROCESSOR_SH4:
builtin_define (TARGET_FPU_SINGLE ? "__SH4_SINGLE__" : "__SH4__");
break;
case PROCESSOR_SH4A: \
builtin_define ("__SH4A__");
builtin_define (TARGET_SH4
? (TARGET_FPU_SINGLE ? "__SH4_SINGLE__" : "__SH4__")
: TARGET_FPU_ANY ? "__SH4_SINGLE_ONLY__"
: "__SH4_NOFPU__");
break;
case PROCESSOR_SH5:
{
builtin_define_with_value ("__SH5__",
TARGET_SHMEDIA64 ? "64" : "32", 0);
builtin_define_with_value ("__SHMEDIA__",
TARGET_SHMEDIA ? "1" : "0", 0);
if (! TARGET_FPU_DOUBLE)
builtin_define ("__SH4_NOFPU__");
}
}
if (TARGET_FPU_ANY)
builtin_define ("__SH_FPU_ANY__");
if (TARGET_FPU_DOUBLE)
builtin_define ("__SH_FPU_DOUBLE__");
if (TARGET_HITACHI)
builtin_define ("__HITACHI__");
if (TARGET_FMOVD)
builtin_define ("__FMOVD_ENABLED__");
builtin_define (TARGET_LITTLE_ENDIAN
? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__");
cpp_define_formatted (pfile, "__SH_ATOMIC_MODEL_%s__",
selected_atomic_model ().cdef_name);
}
...@@ -55,6 +55,14 @@ struct sh_atomic_model ...@@ -55,6 +55,14 @@ struct sh_atomic_model
happen on SH4A. */ happen on SH4A. */
bool strict; bool strict;
enum_type type; enum_type type;
/* Name string as it was specified on the command line. */
const char* name;
/* Name string as it is used in C/C++ defines. */
const char* cdef_name;
/* GBR offset variable for TCB model. */
int tcb_gbr_offset; int tcb_gbr_offset;
}; };
...@@ -156,6 +164,8 @@ extern void sh_canonicalize_comparison (enum rtx_code&, rtx&, rtx&, ...@@ -156,6 +164,8 @@ extern void sh_canonicalize_comparison (enum rtx_code&, rtx&, rtx&,
#endif /* RTX_CODE */ #endif /* RTX_CODE */
extern void sh_cpu_cpp_builtins (cpp_reader* pfile);
extern const char *output_jump_label_table (void); extern const char *output_jump_label_table (void);
extern rtx get_t_reg_rtx (void); extern rtx get_t_reg_rtx (void);
extern rtx get_fpscr_rtx (void); extern rtx get_fpscr_rtx (void);
......
...@@ -619,8 +619,17 @@ parse_validate_atomic_model_option (const char* str) ...@@ -619,8 +619,17 @@ parse_validate_atomic_model_option (const char* str)
model_names[sh_atomic_model::soft_tcb] = "soft-tcb"; model_names[sh_atomic_model::soft_tcb] = "soft-tcb";
model_names[sh_atomic_model::soft_imask] = "soft-imask"; model_names[sh_atomic_model::soft_imask] = "soft-imask";
const char* model_cdef_names[sh_atomic_model::num_models];
model_cdef_names[sh_atomic_model::none] = "NONE";
model_cdef_names[sh_atomic_model::soft_gusa] = "SOFT_GUSA";
model_cdef_names[sh_atomic_model::hard_llcs] = "HARD_LLCS";
model_cdef_names[sh_atomic_model::soft_tcb] = "SOFT_TCB";
model_cdef_names[sh_atomic_model::soft_imask] = "SOFT_IMASK";
sh_atomic_model ret; sh_atomic_model ret;
ret.type = sh_atomic_model::none; ret.type = sh_atomic_model::none;
ret.name = model_names[sh_atomic_model::none];
ret.cdef_name = model_cdef_names[sh_atomic_model::none];
ret.strict = false; ret.strict = false;
ret.tcb_gbr_offset = -1; ret.tcb_gbr_offset = -1;
...@@ -646,6 +655,8 @@ parse_validate_atomic_model_option (const char* str) ...@@ -646,6 +655,8 @@ parse_validate_atomic_model_option (const char* str)
if (tokens.front () == model_names[i]) if (tokens.front () == model_names[i])
{ {
ret.type = (sh_atomic_model::enum_type)i; ret.type = (sh_atomic_model::enum_type)i;
ret.name = model_names[i];
ret.cdef_name = model_cdef_names[i];
goto got_mode_name; goto got_mode_name;
} }
...@@ -677,25 +688,23 @@ got_mode_name:; ...@@ -677,25 +688,23 @@ got_mode_name:;
if (ret.type == sh_atomic_model::soft_gusa && !TARGET_SH3) if (ret.type == sh_atomic_model::soft_gusa && !TARGET_SH3)
err_ret ("atomic model %s is only available on SH3 and SH4 targets", err_ret ("atomic model %s is only available on SH3 and SH4 targets",
model_names[ret.type]); ret.name);
if (ret.type == sh_atomic_model::hard_llcs && !TARGET_SH4A) if (ret.type == sh_atomic_model::hard_llcs && !TARGET_SH4A)
err_ret ("atomic model %s is only available on SH4A targets", err_ret ("atomic model %s is only available on SH4A targets", ret.name);
model_names[ret.type]);
if (ret.type == sh_atomic_model::soft_tcb && ret.tcb_gbr_offset == -1) if (ret.type == sh_atomic_model::soft_tcb && ret.tcb_gbr_offset == -1)
err_ret ("atomic model %s requires gbr-offset parameter", err_ret ("atomic model %s requires gbr-offset parameter", ret.name);
model_names[ret.type]);
if (ret.type == sh_atomic_model::soft_tcb if (ret.type == sh_atomic_model::soft_tcb
&& (ret.tcb_gbr_offset < 0 || ret.tcb_gbr_offset > 1020 && (ret.tcb_gbr_offset < 0 || ret.tcb_gbr_offset > 1020
|| (ret.tcb_gbr_offset & 3) != 0)) || (ret.tcb_gbr_offset & 3) != 0))
err_ret ("invalid gbr-offset value \"%d\" for atomic model %s; it must be " err_ret ("invalid gbr-offset value \"%d\" for atomic model %s; it must be "
"a multiple of 4 in the range 0-1020", ret.tcb_gbr_offset, "a multiple of 4 in the range 0-1020", ret.tcb_gbr_offset,
model_names[ret.type]); ret.name);
if (ret.type == sh_atomic_model::soft_imask && TARGET_USERMODE) if (ret.type == sh_atomic_model::soft_imask && TARGET_USERMODE)
err_ret ("cannot use atomic model %s in user mode", model_names[ret.type]); err_ret ("cannot use atomic model %s in user mode", ret.name);
return ret; return ret;
......
...@@ -31,69 +31,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -31,69 +31,7 @@ along with GCC; see the file COPYING3. If not see
/* ??? No longer true. */ /* ??? No longer true. */
extern int code_for_indirect_jump_scratch; extern int code_for_indirect_jump_scratch;
#define TARGET_CPU_CPP_BUILTINS() \ #define TARGET_CPU_CPP_BUILTINS() sh_cpu_cpp_builtins (pfile)
do { \
builtin_define ("__sh__"); \
builtin_assert ("cpu=sh"); \
builtin_assert ("machine=sh"); \
switch ((int) sh_cpu) \
{ \
case PROCESSOR_SH1: \
builtin_define ("__sh1__"); \
break; \
case PROCESSOR_SH2: \
builtin_define ("__sh2__"); \
break; \
case PROCESSOR_SH2E: \
builtin_define ("__SH2E__"); \
break; \
case PROCESSOR_SH2A: \
builtin_define ("__SH2A__"); \
builtin_define (TARGET_SH2A_DOUBLE \
? (TARGET_FPU_SINGLE ? "__SH2A_SINGLE__" : "__SH2A_DOUBLE__") \
: TARGET_FPU_ANY ? "__SH2A_SINGLE_ONLY__" \
: "__SH2A_NOFPU__"); \
break; \
case PROCESSOR_SH3: \
builtin_define ("__sh3__"); \
builtin_define ("__SH3__"); \
if (TARGET_HARD_SH4) \
builtin_define ("__SH4_NOFPU__"); \
break; \
case PROCESSOR_SH3E: \
builtin_define (TARGET_HARD_SH4 ? "__SH4_SINGLE_ONLY__" : "__SH3E__"); \
break; \
case PROCESSOR_SH4: \
builtin_define (TARGET_FPU_SINGLE ? "__SH4_SINGLE__" : "__SH4__"); \
break; \
case PROCESSOR_SH4A: \
builtin_define ("__SH4A__"); \
builtin_define (TARGET_SH4 \
? (TARGET_FPU_SINGLE ? "__SH4_SINGLE__" : "__SH4__") \
: TARGET_FPU_ANY ? "__SH4_SINGLE_ONLY__" \
: "__SH4_NOFPU__"); \
break; \
case PROCESSOR_SH5: \
{ \
builtin_define_with_value ("__SH5__", \
TARGET_SHMEDIA64 ? "64" : "32", 0); \
builtin_define_with_value ("__SHMEDIA__", \
TARGET_SHMEDIA ? "1" : "0", 0); \
if (! TARGET_FPU_DOUBLE) \
builtin_define ("__SH4_NOFPU__"); \
} \
} \
if (TARGET_FPU_ANY) \
builtin_define ("__SH_FPU_ANY__"); \
if (TARGET_FPU_DOUBLE) \
builtin_define ("__SH_FPU_DOUBLE__"); \
if (TARGET_HITACHI) \
builtin_define ("__HITACHI__"); \
if (TARGET_FMOVD) \
builtin_define ("__FMOVD_ENABLED__"); \
builtin_define (TARGET_LITTLE_ENDIAN \
? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \
} while (0)
/* Value should be nonzero if functions must have frame pointers. /* Value should be nonzero if functions must have frame pointers.
Zero means the frame pointer need not be set up (and parms may be accessed Zero means the frame pointer need not be set up (and parms may be accessed
......
2012-10-03 Oleg Endo <olegendo@gcc.gnu.org>
PR target/50457
* config/sh/linux-atomic.S: Delete.
* config/sh/linux-atomic.c: New.
* config/sh/t-linux (LIB2ADD): Replace linux-atomic.S with
linux-atomic.c. Add cflags to disable warnings.
2012-10-02 Jonathan Wakely <jwakely.gcc@gmail.com> 2012-10-02 Jonathan Wakely <jwakely.gcc@gmail.com>
PR other/53889 PR other/53889
...@@ -16,8 +24,8 @@ ...@@ -16,8 +24,8 @@
2012-09-19 Mark Kettenis <kettenis@openbsd.org> 2012-09-19 Mark Kettenis <kettenis@openbsd.org>
* config.host (hppa-*-openbsd*): New target. * config.host (hppa-*-openbsd*): New target.
* config/pa/t-openbsd: New file. * config/pa/t-openbsd: New file.
2012-09-15 Georg-Johann Lay <avr@gjlay.de> 2012-09-15 Georg-Johann Lay <avr@gjlay.de>
...@@ -50,9 +58,9 @@ ...@@ -50,9 +58,9 @@
2012-09-07 Teresa Johnson <tejohnson@google.com> 2012-09-07 Teresa Johnson <tejohnson@google.com>
PR gcov-profile/54487 PR gcov-profile/54487
* libgcc/libgcov.c (gcov_exit): Avoid warning on histogram * libgcc/libgcov.c (gcov_exit): Avoid warning on histogram
differences. differences.
2012-09-05 Georg-Johann Lay <avr@gjlay.de> 2012-09-05 Georg-Johann Lay <avr@gjlay.de>
......
/* Copyright (C) 2006, 2008, 2009 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
!! Linux specific atomic routines for the Renesas / SuperH SH CPUs.
!! Linux kernel for SH3/4 has implemented the support for software
!! atomic sequences.
#define FUNC(X) .type X,@function
#define HIDDEN_FUNC(X) FUNC(X); .hidden X
#define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X
#define ENDFUNC(X) ENDFUNC0(X)
#if ! __SH5__
#define ATOMIC_TEST_AND_SET(N,T,EXT) \
.global __sync_lock_test_and_set_##N; \
HIDDEN_FUNC(__sync_lock_test_and_set_##N); \
.align 2; \
__sync_lock_test_and_set_##N:; \
mova 1f, r0; \
nop; \
mov r15, r1; \
mov #(0f-1f), r15; \
0: mov.##T @r4, r2; \
mov.##T r5, @r4; \
1: mov r1, r15; \
rts; \
EXT r2, r0; \
ENDFUNC(__sync_lock_test_and_set_##N)
ATOMIC_TEST_AND_SET (1,b,extu.b)
ATOMIC_TEST_AND_SET (2,w,extu.w)
ATOMIC_TEST_AND_SET (4,l,mov)
#define ATOMIC_COMPARE_AND_SWAP(N,T,EXTS,EXT) \
.global __sync_val_compare_and_swap_##N; \
HIDDEN_FUNC(__sync_val_compare_and_swap_##N); \
.align 2; \
__sync_val_compare_and_swap_##N:; \
mova 1f, r0; \
EXTS r5, r5; \
mov r15, r1; \
mov #(0f-1f), r15; \
0: mov.##T @r4, r2; \
cmp/eq r2, r5; \
bf 1f; \
mov.##T r6, @r4; \
1: mov r1, r15; \
rts; \
EXT r2, r0; \
ENDFUNC(__sync_val_compare_and_swap_##N)
ATOMIC_COMPARE_AND_SWAP (1,b,exts.b,extu.b)
ATOMIC_COMPARE_AND_SWAP (2,w,exts.w,extu.w)
ATOMIC_COMPARE_AND_SWAP (4,l,mov,mov)
#define ATOMIC_BOOL_COMPARE_AND_SWAP(N,T,EXTS) \
.global __sync_bool_compare_and_swap_##N; \
HIDDEN_FUNC(__sync_bool_compare_and_swap_##N); \
.align 2; \
__sync_bool_compare_and_swap_##N:; \
mova 1f, r0; \
EXTS r5, r5; \
mov r15, r1; \
mov #(0f-1f), r15; \
0: mov.##T @r4, r2; \
cmp/eq r2, r5; \
bf 1f; \
mov.##T r6, @r4; \
1: mov r1, r15; \
rts; \
movt r0; \
ENDFUNC(__sync_bool_compare_and_swap_##N)
ATOMIC_BOOL_COMPARE_AND_SWAP (1,b,exts.b)
ATOMIC_BOOL_COMPARE_AND_SWAP (2,w,exts.w)
ATOMIC_BOOL_COMPARE_AND_SWAP (4,l,mov)
#define ATOMIC_FETCH_AND_OP(OP,N,T,EXT) \
.global __sync_fetch_and_##OP##_##N; \
HIDDEN_FUNC(__sync_fetch_and_##OP##_##N); \
.align 2; \
__sync_fetch_and_##OP##_##N:; \
mova 1f, r0; \
nop; \
mov r15, r1; \
mov #(0f-1f), r15; \
0: mov.##T @r4, r2; \
mov r5, r3; \
OP r2, r3; \
mov.##T r3, @r4; \
1: mov r1, r15; \
rts; \
EXT r2, r0; \
ENDFUNC(__sync_fetch_and_##OP##_##N)
ATOMIC_FETCH_AND_OP(add,1,b,extu.b)
ATOMIC_FETCH_AND_OP(add,2,w,extu.w)
ATOMIC_FETCH_AND_OP(add,4,l,mov)
ATOMIC_FETCH_AND_OP(or,1,b,extu.b)
ATOMIC_FETCH_AND_OP(or,2,w,extu.w)
ATOMIC_FETCH_AND_OP(or,4,l,mov)
ATOMIC_FETCH_AND_OP(and,1,b,extu.b)
ATOMIC_FETCH_AND_OP(and,2,w,extu.w)
ATOMIC_FETCH_AND_OP(and,4,l,mov)
ATOMIC_FETCH_AND_OP(xor,1,b,extu.b)
ATOMIC_FETCH_AND_OP(xor,2,w,extu.w)
ATOMIC_FETCH_AND_OP(xor,4,l,mov)
#define ATOMIC_FETCH_AND_COMBOP(OP,OP0,OP1,N,T,EXT) \
.global __sync_fetch_and_##OP##_##N; \
HIDDEN_FUNC(__sync_fetch_and_##OP##_##N); \
.align 2; \
__sync_fetch_and_##OP##_##N:; \
mova 1f, r0; \
mov r15, r1; \
mov #(0f-1f), r15; \
0: mov.##T @r4, r2; \
mov r5, r3; \
OP0 r2, r3; \
OP1 r3, r3; \
mov.##T r3, @r4; \
1: mov r1, r15; \
rts; \
EXT r2, r0; \
ENDFUNC(__sync_fetch_and_##OP##_##N)
ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,1,b,extu.b)
ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,2,w,extu.w)
ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,4,l,mov)
ATOMIC_FETCH_AND_COMBOP(nand,and,not,1,b,extu.b)
ATOMIC_FETCH_AND_COMBOP(nand,and,not,2,w,extu.w)
ATOMIC_FETCH_AND_COMBOP(nand,and,not,4,l,mov)
#define ATOMIC_OP_AND_FETCH(OP,N,T,EXT) \
.global __sync_##OP##_and_fetch_##N; \
HIDDEN_FUNC(__sync_##OP##_and_fetch_##N); \
.align 2; \
__sync_##OP##_and_fetch_##N:; \
mova 1f, r0; \
nop; \
mov r15, r1; \
mov #(0f-1f), r15; \
0: mov.##T @r4, r2; \
mov r5, r3; \
OP r2, r3; \
mov.##T r3, @r4; \
1: mov r1, r15; \
rts; \
EXT r3, r0; \
ENDFUNC(__sync_##OP##_and_fetch_##N)
ATOMIC_OP_AND_FETCH(add,1,b,extu.b)
ATOMIC_OP_AND_FETCH(add,2,w,extu.w)
ATOMIC_OP_AND_FETCH(add,4,l,mov)
ATOMIC_OP_AND_FETCH(or,1,b,extu.b)
ATOMIC_OP_AND_FETCH(or,2,w,extu.w)
ATOMIC_OP_AND_FETCH(or,4,l,mov)
ATOMIC_OP_AND_FETCH(and,1,b,extu.b)
ATOMIC_OP_AND_FETCH(and,2,w,extu.w)
ATOMIC_OP_AND_FETCH(and,4,l,mov)
ATOMIC_OP_AND_FETCH(xor,1,b,extu.b)
ATOMIC_OP_AND_FETCH(xor,2,w,extu.w)
ATOMIC_OP_AND_FETCH(xor,4,l,mov)
#define ATOMIC_COMBOP_AND_FETCH(OP,OP0,OP1,N,T,EXT) \
.global __sync_##OP##_and_fetch_##N; \
HIDDEN_FUNC(__sync_##OP##_and_fetch_##N); \
.align 2; \
__sync_##OP##_and_fetch_##N:; \
mova 1f, r0; \
mov r15, r1; \
mov #(0f-1f), r15; \
0: mov.##T @r4, r2; \
mov r5, r3; \
OP0 r2, r3; \
OP1 r3, r3; \
mov.##T r3, @r4; \
1: mov r1, r15; \
rts; \
EXT r3, r0; \
ENDFUNC(__sync_##OP##_and_fetch_##N)
ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,1,b,extu.b)
ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,2,w,extu.w)
ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,4,l,mov)
ATOMIC_COMBOP_AND_FETCH(nand,and,not,1,b,extu.b)
ATOMIC_COMBOP_AND_FETCH(nand,and,not,2,w,extu.w)
ATOMIC_COMBOP_AND_FETCH(nand,and,not,4,l,mov)
.section .note.GNU-stack,"",%progbits
.previous
#endif /* ! __SH5__ */
/* Copyright (C) 2012 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* Atomic built-in C functions for link compatibility with older code that
was compiled to emit function calls for atomic built-ins.
Notice that if no atomic model has been selected the functions in this
file must not be generated, or else they will result in infinite no-op
loops.
Notice also, that all the generated functions below take three parameters,
which is not actually true for some of the built-in functions. However,
on SH this does not matter, since the first four parameters are always
passed in call clobbered registers.
The return type for the sync_bool_compare_and_swap functions is also
actually supposed to be a bool, but this also doesn't matter since any
int return type <= 32 bit is returned in R0 on SH. */
#if !__SH_ATOMIC_MODEL_NONE__
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#define uint8_t_sz 1
#define uint16_t_sz 2
#define uint32_t_sz 4
#define typesz(x) x##_sz
#define concat(x,y) __ ## x ## _ ## y
#define eval(x,y) concat (x,y)
#define genname(f,t) eval(f, typesz (t))
#define func1(name, type) \
type __attribute__((visibility("hidden"))) \
genname (name, type) (type* x, type y, type z) \
{ \
return __##name (x, y, z); \
}
#define genfuncs(name) \
func1 (name, uint8_t) \
func1 (name, uint16_t) \
func1 (name, uint32_t)
genfuncs (sync_lock_test_and_set)
genfuncs (sync_val_compare_and_swap)
genfuncs (sync_bool_compare_and_swap)
genfuncs (sync_fetch_and_add)
genfuncs (sync_fetch_and_or)
genfuncs (sync_fetch_and_and)
genfuncs (sync_fetch_and_xor)
genfuncs (sync_fetch_and_sub)
genfuncs (sync_fetch_and_nand)
genfuncs (sync_add_and_fetch)
genfuncs (sync_or_and_fetch)
genfuncs (sync_and_and_fetch)
genfuncs (sync_xor_and_fetch)
genfuncs (sync_sub_and_fetch)
genfuncs (sync_nand_and_fetch)
#endif
LIB1ASMFUNCS_CACHE = _ic_invalidate _ic_invalidate_array LIB1ASMFUNCS_CACHE = _ic_invalidate _ic_invalidate_array
LIB2ADD = $(srcdir)/config/sh/linux-atomic.S LIB2ADD = $(srcdir)/config/sh/linux-atomic.c
HOST_LIBGCC2_CFLAGS += -mieee -DNO_FPSCR_VALUES HOST_LIBGCC2_CFLAGS += -mieee -DNO_FPSCR_VALUES
# Silence atomic built-in related warnings in linux-atomic.c.
# Unfortunately the conflicting types warning can't be disabled selectively.
HOST_LIBGCC2_CFLAGS += -w -Wno-sync-nand
# Override t-slibgcc-elf-ver to export some libgcc symbols with # Override t-slibgcc-elf-ver to export some libgcc symbols with
# the symbol versions that glibc used, and hide some lib1func # the symbol versions that glibc used, and hide some lib1func
# routines which should not be called via PLT. We have to create # routines which should not be called via PLT. We have to create
......
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