Brig front-end
2017-01-24 Pekka Jääskeläinen <pekka@parmance.com> Martin Jambor <mjambor@suse.cz> * Makefile.def (target_modules): Added libhsail-rt. (languages): Added language brig. * Makefile.in: Regenerated. * configure.ac (TOPLEVEL_CONFIGURE_ARGUMENTS): Added tgarget-libhsail-rt. Make brig unsupported on untested architectures. * configure: Regenerated. gcc/ * brig-builtins.def: New file. * builtins.def (DEF_HSAIL_BUILTIN): New macro. (DEF_HSAIL_ATOMIC_BUILTIN): Likewise. (DEF_HSAIL_SAT_BUILTIN): Likewise. (DEF_HSAIL_INTR_BUILTIN): Likewise. (DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN): Likewise. * builtin-types.def (BT_INT8): New. (BT_INT16): Likewise. (BT_UINT8): Likewise. (BT_UINT16): Likewise. (BT_FN_ULONG): Likewise. (BT_FN_UINT_INT): Likewise. (BT_FN_UINT_ULONG): Likewise. (BT_FN_UINT_LONG): Likewise. (BT_FN_UINT_PTR): Likewise. (BT_FN_ULONG_PTR): Likewise. (BT_FN_INT8_FLOAT): Likewise. (BT_FN_INT16_FLOAT): Likewise. (BT_FN_UINT32_FLOAT): Likewise. (BT_FN_UINT16_FLOAT): Likewise. (BT_FN_UINT8_FLOAT): Likewise. (BT_FN_UINT64_FLOAT): Likewise. (BT_FN_UINT16_UINT32): Likewise. (BT_FN_UINT32_UINT16): Likewise. (BT_FN_UINT16_UINT16_UINT16): Likewise. (BT_FN_INT_PTR_INT): Likewise. (BT_FN_UINT_PTR_UINT): Likewise. (BT_FN_LONG_PTR_LONG): Likewise. (BT_FN_ULONG_PTR_ULONG): Likewise. (BT_FN_VOID_UINT64_UINT64): Likewise. (BT_FN_UINT8_UINT8_UINT8): Likewise. (BT_FN_INT8_INT8_INT8): Likewise. (BT_FN_INT16_INT16_INT16): Likewise. (BT_FN_INT_INT_INT): Likewise. (BT_FN_UINT_FLOAT_UINT): Likewise. (BT_FN_FLOAT_UINT_UINT): Likewise. (BT_FN_ULONG_UINT_UINT): Likewise. (BT_FN_ULONG_UINT_PTR): Likewise. (BT_FN_ULONG_ULONG_ULONG): Likewise. (BT_FN_UINT_UINT_UINT): Likewise. (BT_FN_VOID_UINT_PTR): Likewise. (BT_FN_UINT_UINT_PTR: Likewise. (BT_FN_UINT32_UINT64_PTR): Likewise. (BT_FN_INT_INT_UINT_UINT): Likewise. (BT_FN_UINT_UINT_UINT_UINT): Likewise. (BT_FN_UINT_UINT_UINT_PTR): Likewise. (BT_FN_UINT_ULONG_ULONG_UINT): Likewise. (BT_FN_ULONG_ULONG_ULONG_ULONG): Likewise. (BT_FN_LONG_LONG_UINT_UINT): Likewise. (BT_FN_ULONG_ULONG_UINT_UINT): Likewise. (BT_FN_VOID_UINT32_UINT64_PTR): Likewise. (BT_FN_VOID_UINT32_UINT32_PTR): Likewise. (BT_FN_UINT_UINT_UINT_UINT_UINT): Likewise. (BT_FN_UINT_FLOAT_FLOAT_FLOAT_FLOAT): Likewise. (BT_FN_ULONG_ULONG_ULONG_UINT_UINT): Likewise. * doc/frontends.texi: List BRIG FE. * doc/install.texi (Testing): Add BRIG tesring requirements. * doc/invoke.texi (Overall Options): Mention BRIG. * doc/standards.texi (Standards): Doucment BRIG HSA version. gcc/brig/ * Make-lang.in: New file. * brig-builtins.h: Likewise. * brig-c.h: Likewise. * brig-lang.c: Likewise. * brigspec.c: Likewise. * config-lang.in: Likewise. * lang-specs.h: Likewise. * lang.opt: Likewise. * brigfrontend/brig-arg-block-handler.cc: Likewise. * brigfrontend/brig-atomic-inst-handler.cc: Likewise. * brigfrontend/brig-basic-inst-handler.cc: Likewise. * brigfrontend/brig-branch-inst-handler.cc: Likewise. * brigfrontend/brig-cmp-inst-handler.cc: Likewise. * brigfrontend/brig-code-entry-handler.cc: Likewise. * brigfrontend/brig-code-entry-handler.h: Likewise. * brigfrontend/brig-comment-handler.cc: Likewise. * brigfrontend/brig-control-handler.cc: Likewise. * brigfrontend/brig-copy-move-inst-handler.cc: Likewise. * brigfrontend/brig-cvt-inst-handler.cc: Likewise. * brigfrontend/brig-fbarrier-handler.cc: Likewise. * brigfrontend/brig-function-handler.cc: Likewise. * brigfrontend/brig-function.cc: Likewise. * brigfrontend/brig-function.h: Likewise. * brigfrontend/brig-inst-mod-handler.cc: Likewise. * brigfrontend/brig-label-handler.cc: Likewise. * brigfrontend/brig-lane-inst-handler.cc: Likewise. * brigfrontend/brig-machine.c: Likewise. * brigfrontend/brig-machine.h: Likewise. * brigfrontend/brig-mem-inst-handler.cc: Likewise. * brigfrontend/brig-module-handler.cc: Likewise. * brigfrontend/brig-queue-inst-handler.cc: Likewise. * brigfrontend/brig-seg-inst-handler.cc: Likewise. * brigfrontend/brig-signal-inst-handler.cc: Likewise. * brigfrontend/brig-to-generic.cc: Likewise. * brigfrontend/brig-to-generic.h: Likewise. * brigfrontend/brig-util.cc: Likewise. * brigfrontend/brig-util.h: Likewise. * brigfrontend/brig-variable-handler.cc: Likewise. * brigfrontend/phsa.h: Likewise. gcc/testsuite/ * lib/brig-dg.exp: New file. * lib/brig.exp: Likewise. * brig.dg/README: Likewise. * brig.dg/dg.exp: Likewise. * brig.dg/test/gimple/alloca.hsail: Likewise. * brig.dg/test/gimple/atomics.hsail: Likewise. * brig.dg/test/gimple/branches.hsail: Likewise. * brig.dg/test/gimple/fbarrier.hsail: Likewise. * brig.dg/test/gimple/function_calls.hsail: Likewise. * brig.dg/test/gimple/kernarg.hsail: Likewise. * brig.dg/test/gimple/mem.hsail: Likewise. * brig.dg/test/gimple/mulhi.hsail: Likewise. * brig.dg/test/gimple/packed.hsail: Likewise. * brig.dg/test/gimple/smoke_test.hsail: Likewise. * brig.dg/test/gimple/variables.hsail: Likewise. * brig.dg/test/gimple/vector.hsail: Likewise. include/ * hsa.h: Moved here from libgomp/plugin/hsa.h. libgomp/ * plugin/hsa.h: Moved to top level include. * plugin/plugin-hsa.c: Chanfgd include of hsa.h accordingly. libhsail-rt/ * Makefile.am: New file. * target-config.h.in: Likewise. * configure.ac: Likewise. * configure: Likewise. * config.h.in: Likewise. * aclocal.m4: Likewise. * README: Likewise. * Makefile.in: Likewise. * include/internal/fibers.h: Likewise. * include/internal/phsa-queue-interface.h: Likewise. * include/internal/phsa-rt.h: Likewise. * include/internal/workitems.h: Likewise. * rt/arithmetic.c: Likewise. * rt/atomics.c: Likewise. * rt/bitstring.c: Likewise. * rt/fbarrier.c: Likewise. * rt/fibers.c: Likewise. * rt/fp16.c: Likewise. * rt/misc.c: Likewise. * rt/multimedia.c: Likewise. * rt/queue.c: Likewise. * rt/sat_arithmetic.c: Likewise. * rt/segment.c: Likewise. * rt/workitems.c: Likewise. Co-Authored-By: Martin Jambor <mjambor@suse.cz> From-SVN: r244867
This commit is contained in:
parent
e1e41b6f10
commit
5fd1486ce5
99 changed files with 34461 additions and 4 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2017-01-24 Pekka Jääskeläinen <pekka@parmance.com>
|
||||
Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
|
||||
* Makefile.def (target_modules): Added libhsail-rt.
|
||||
(languages): Added language brig.
|
||||
* Makefile.in: Regenerated.
|
||||
* configure.ac (TOPLEVEL_CONFIGURE_ARGUMENTS): Added
|
||||
tgarget-libhsail-rt. Make brig unsupported on untested architectures.
|
||||
* configure: Regenerated.
|
||||
|
||||
2017-01-19 Uros Bizjak <ubizjak@gmail.com>
|
||||
|
||||
PR target/78478
|
||||
|
|
|
@ -157,6 +157,7 @@ target_modules = { module= libquadmath; };
|
|||
target_modules = { module= libgfortran; };
|
||||
target_modules = { module= libobjc; };
|
||||
target_modules = { module= libgo; };
|
||||
target_modules = { module= libhsail-rt; };
|
||||
target_modules = { module= libtermcap; no_check=true;
|
||||
missing=mostlyclean;
|
||||
missing=clean;
|
||||
|
@ -601,6 +602,8 @@ languages = { language=objc; gcc-check-target=check-objc;
|
|||
languages = { language=obj-c++; gcc-check-target=check-obj-c++; };
|
||||
languages = { language=go; gcc-check-target=check-go;
|
||||
lib-check-target=check-target-libgo; };
|
||||
languages = { language=brig; gcc-check-target=check-brig;
|
||||
lib-check-target=check-target-libhsail-rt; };
|
||||
|
||||
// Toplevel bootstrap
|
||||
bootstrap_stage = { id=1 ; };
|
||||
|
|
489
Makefile.in
489
Makefile.in
|
@ -993,6 +993,7 @@ configure-target: \
|
|||
maybe-configure-target-libgfortran \
|
||||
maybe-configure-target-libobjc \
|
||||
maybe-configure-target-libgo \
|
||||
maybe-configure-target-libhsail-rt \
|
||||
maybe-configure-target-libtermcap \
|
||||
maybe-configure-target-winsup \
|
||||
maybe-configure-target-libgloss \
|
||||
|
@ -1158,6 +1159,7 @@ all-target: maybe-all-target-libquadmath
|
|||
all-target: maybe-all-target-libgfortran
|
||||
all-target: maybe-all-target-libobjc
|
||||
all-target: maybe-all-target-libgo
|
||||
all-target: maybe-all-target-libhsail-rt
|
||||
all-target: maybe-all-target-libtermcap
|
||||
all-target: maybe-all-target-winsup
|
||||
all-target: maybe-all-target-libgloss
|
||||
|
@ -1250,6 +1252,7 @@ info-target: maybe-info-target-libquadmath
|
|||
info-target: maybe-info-target-libgfortran
|
||||
info-target: maybe-info-target-libobjc
|
||||
info-target: maybe-info-target-libgo
|
||||
info-target: maybe-info-target-libhsail-rt
|
||||
info-target: maybe-info-target-libtermcap
|
||||
info-target: maybe-info-target-winsup
|
||||
info-target: maybe-info-target-libgloss
|
||||
|
@ -1335,6 +1338,7 @@ dvi-target: maybe-dvi-target-libquadmath
|
|||
dvi-target: maybe-dvi-target-libgfortran
|
||||
dvi-target: maybe-dvi-target-libobjc
|
||||
dvi-target: maybe-dvi-target-libgo
|
||||
dvi-target: maybe-dvi-target-libhsail-rt
|
||||
dvi-target: maybe-dvi-target-libtermcap
|
||||
dvi-target: maybe-dvi-target-winsup
|
||||
dvi-target: maybe-dvi-target-libgloss
|
||||
|
@ -1420,6 +1424,7 @@ pdf-target: maybe-pdf-target-libquadmath
|
|||
pdf-target: maybe-pdf-target-libgfortran
|
||||
pdf-target: maybe-pdf-target-libobjc
|
||||
pdf-target: maybe-pdf-target-libgo
|
||||
pdf-target: maybe-pdf-target-libhsail-rt
|
||||
pdf-target: maybe-pdf-target-libtermcap
|
||||
pdf-target: maybe-pdf-target-winsup
|
||||
pdf-target: maybe-pdf-target-libgloss
|
||||
|
@ -1505,6 +1510,7 @@ html-target: maybe-html-target-libquadmath
|
|||
html-target: maybe-html-target-libgfortran
|
||||
html-target: maybe-html-target-libobjc
|
||||
html-target: maybe-html-target-libgo
|
||||
html-target: maybe-html-target-libhsail-rt
|
||||
html-target: maybe-html-target-libtermcap
|
||||
html-target: maybe-html-target-winsup
|
||||
html-target: maybe-html-target-libgloss
|
||||
|
@ -1590,6 +1596,7 @@ TAGS-target: maybe-TAGS-target-libquadmath
|
|||
TAGS-target: maybe-TAGS-target-libgfortran
|
||||
TAGS-target: maybe-TAGS-target-libobjc
|
||||
TAGS-target: maybe-TAGS-target-libgo
|
||||
TAGS-target: maybe-TAGS-target-libhsail-rt
|
||||
TAGS-target: maybe-TAGS-target-libtermcap
|
||||
TAGS-target: maybe-TAGS-target-winsup
|
||||
TAGS-target: maybe-TAGS-target-libgloss
|
||||
|
@ -1675,6 +1682,7 @@ install-info-target: maybe-install-info-target-libquadmath
|
|||
install-info-target: maybe-install-info-target-libgfortran
|
||||
install-info-target: maybe-install-info-target-libobjc
|
||||
install-info-target: maybe-install-info-target-libgo
|
||||
install-info-target: maybe-install-info-target-libhsail-rt
|
||||
install-info-target: maybe-install-info-target-libtermcap
|
||||
install-info-target: maybe-install-info-target-winsup
|
||||
install-info-target: maybe-install-info-target-libgloss
|
||||
|
@ -1760,6 +1768,7 @@ install-pdf-target: maybe-install-pdf-target-libquadmath
|
|||
install-pdf-target: maybe-install-pdf-target-libgfortran
|
||||
install-pdf-target: maybe-install-pdf-target-libobjc
|
||||
install-pdf-target: maybe-install-pdf-target-libgo
|
||||
install-pdf-target: maybe-install-pdf-target-libhsail-rt
|
||||
install-pdf-target: maybe-install-pdf-target-libtermcap
|
||||
install-pdf-target: maybe-install-pdf-target-winsup
|
||||
install-pdf-target: maybe-install-pdf-target-libgloss
|
||||
|
@ -1845,6 +1854,7 @@ install-html-target: maybe-install-html-target-libquadmath
|
|||
install-html-target: maybe-install-html-target-libgfortran
|
||||
install-html-target: maybe-install-html-target-libobjc
|
||||
install-html-target: maybe-install-html-target-libgo
|
||||
install-html-target: maybe-install-html-target-libhsail-rt
|
||||
install-html-target: maybe-install-html-target-libtermcap
|
||||
install-html-target: maybe-install-html-target-winsup
|
||||
install-html-target: maybe-install-html-target-libgloss
|
||||
|
@ -1930,6 +1940,7 @@ installcheck-target: maybe-installcheck-target-libquadmath
|
|||
installcheck-target: maybe-installcheck-target-libgfortran
|
||||
installcheck-target: maybe-installcheck-target-libobjc
|
||||
installcheck-target: maybe-installcheck-target-libgo
|
||||
installcheck-target: maybe-installcheck-target-libhsail-rt
|
||||
installcheck-target: maybe-installcheck-target-libtermcap
|
||||
installcheck-target: maybe-installcheck-target-winsup
|
||||
installcheck-target: maybe-installcheck-target-libgloss
|
||||
|
@ -2015,6 +2026,7 @@ mostlyclean-target: maybe-mostlyclean-target-libquadmath
|
|||
mostlyclean-target: maybe-mostlyclean-target-libgfortran
|
||||
mostlyclean-target: maybe-mostlyclean-target-libobjc
|
||||
mostlyclean-target: maybe-mostlyclean-target-libgo
|
||||
mostlyclean-target: maybe-mostlyclean-target-libhsail-rt
|
||||
mostlyclean-target: maybe-mostlyclean-target-libtermcap
|
||||
mostlyclean-target: maybe-mostlyclean-target-winsup
|
||||
mostlyclean-target: maybe-mostlyclean-target-libgloss
|
||||
|
@ -2100,6 +2112,7 @@ clean-target: maybe-clean-target-libquadmath
|
|||
clean-target: maybe-clean-target-libgfortran
|
||||
clean-target: maybe-clean-target-libobjc
|
||||
clean-target: maybe-clean-target-libgo
|
||||
clean-target: maybe-clean-target-libhsail-rt
|
||||
clean-target: maybe-clean-target-libtermcap
|
||||
clean-target: maybe-clean-target-winsup
|
||||
clean-target: maybe-clean-target-libgloss
|
||||
|
@ -2185,6 +2198,7 @@ distclean-target: maybe-distclean-target-libquadmath
|
|||
distclean-target: maybe-distclean-target-libgfortran
|
||||
distclean-target: maybe-distclean-target-libobjc
|
||||
distclean-target: maybe-distclean-target-libgo
|
||||
distclean-target: maybe-distclean-target-libhsail-rt
|
||||
distclean-target: maybe-distclean-target-libtermcap
|
||||
distclean-target: maybe-distclean-target-winsup
|
||||
distclean-target: maybe-distclean-target-libgloss
|
||||
|
@ -2270,6 +2284,7 @@ maintainer-clean-target: maybe-maintainer-clean-target-libquadmath
|
|||
maintainer-clean-target: maybe-maintainer-clean-target-libgfortran
|
||||
maintainer-clean-target: maybe-maintainer-clean-target-libobjc
|
||||
maintainer-clean-target: maybe-maintainer-clean-target-libgo
|
||||
maintainer-clean-target: maybe-maintainer-clean-target-libhsail-rt
|
||||
maintainer-clean-target: maybe-maintainer-clean-target-libtermcap
|
||||
maintainer-clean-target: maybe-maintainer-clean-target-winsup
|
||||
maintainer-clean-target: maybe-maintainer-clean-target-libgloss
|
||||
|
@ -2411,6 +2426,7 @@ check-target: \
|
|||
maybe-check-target-libgfortran \
|
||||
maybe-check-target-libobjc \
|
||||
maybe-check-target-libgo \
|
||||
maybe-check-target-libhsail-rt \
|
||||
maybe-check-target-libtermcap \
|
||||
maybe-check-target-winsup \
|
||||
maybe-check-target-libgloss \
|
||||
|
@ -2592,6 +2608,7 @@ install-target: \
|
|||
maybe-install-target-libgfortran \
|
||||
maybe-install-target-libobjc \
|
||||
maybe-install-target-libgo \
|
||||
maybe-install-target-libhsail-rt \
|
||||
maybe-install-target-libtermcap \
|
||||
maybe-install-target-winsup \
|
||||
maybe-install-target-libgloss \
|
||||
|
@ -2697,6 +2714,7 @@ install-strip-target: \
|
|||
maybe-install-strip-target-libgfortran \
|
||||
maybe-install-strip-target-libobjc \
|
||||
maybe-install-strip-target-libgo \
|
||||
maybe-install-strip-target-libhsail-rt \
|
||||
maybe-install-strip-target-libtermcap \
|
||||
maybe-install-strip-target-winsup \
|
||||
maybe-install-strip-target-libgloss \
|
||||
|
@ -46096,6 +46114,464 @@ maintainer-clean-target-libgo:
|
|||
|
||||
|
||||
|
||||
.PHONY: configure-target-libhsail-rt maybe-configure-target-libhsail-rt
|
||||
maybe-configure-target-libhsail-rt:
|
||||
@if gcc-bootstrap
|
||||
configure-target-libhsail-rt: stage_current
|
||||
@endif gcc-bootstrap
|
||||
@if target-libhsail-rt
|
||||
maybe-configure-target-libhsail-rt: configure-target-libhsail-rt
|
||||
configure-target-libhsail-rt:
|
||||
@: $(MAKE); $(unstage)
|
||||
@r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
echo "Checking multilib configuration for libhsail-rt..."; \
|
||||
$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libhsail-rt; \
|
||||
$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libhsail-rt/multilib.tmp 2> /dev/null; \
|
||||
if test -r $(TARGET_SUBDIR)/libhsail-rt/multilib.out; then \
|
||||
if cmp -s $(TARGET_SUBDIR)/libhsail-rt/multilib.tmp $(TARGET_SUBDIR)/libhsail-rt/multilib.out; then \
|
||||
rm -f $(TARGET_SUBDIR)/libhsail-rt/multilib.tmp; \
|
||||
else \
|
||||
rm -f $(TARGET_SUBDIR)/libhsail-rt/Makefile; \
|
||||
mv $(TARGET_SUBDIR)/libhsail-rt/multilib.tmp $(TARGET_SUBDIR)/libhsail-rt/multilib.out; \
|
||||
fi; \
|
||||
else \
|
||||
mv $(TARGET_SUBDIR)/libhsail-rt/multilib.tmp $(TARGET_SUBDIR)/libhsail-rt/multilib.out; \
|
||||
fi; \
|
||||
test ! -f $(TARGET_SUBDIR)/libhsail-rt/Makefile || exit 0; \
|
||||
$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libhsail-rt; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo Configuring in $(TARGET_SUBDIR)/libhsail-rt; \
|
||||
cd "$(TARGET_SUBDIR)/libhsail-rt" || exit 1; \
|
||||
case $(srcdir) in \
|
||||
/* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
|
||||
*) topdir=`echo $(TARGET_SUBDIR)/libhsail-rt/ | \
|
||||
sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
|
||||
esac; \
|
||||
module_srcdir=libhsail-rt; \
|
||||
rm -f no-such-file || : ; \
|
||||
CONFIG_SITE=no-such-file $(SHELL) \
|
||||
$$s/$$module_srcdir/configure \
|
||||
--srcdir=$${topdir}/$$module_srcdir \
|
||||
$(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
|
||||
--target=${target_alias} \
|
||||
|| exit 1
|
||||
@endif target-libhsail-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.PHONY: all-target-libhsail-rt maybe-all-target-libhsail-rt
|
||||
maybe-all-target-libhsail-rt:
|
||||
@if gcc-bootstrap
|
||||
all-target-libhsail-rt: stage_current
|
||||
@endif gcc-bootstrap
|
||||
@if target-libhsail-rt
|
||||
TARGET-target-libhsail-rt=all
|
||||
maybe-all-target-libhsail-rt: all-target-libhsail-rt
|
||||
all-target-libhsail-rt: configure-target-libhsail-rt
|
||||
@: $(MAKE); $(unstage)
|
||||
@r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_TARGET_FLAGS) \
|
||||
$(TARGET-target-libhsail-rt))
|
||||
@endif target-libhsail-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.PHONY: check-target-libhsail-rt maybe-check-target-libhsail-rt
|
||||
maybe-check-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-check-target-libhsail-rt: check-target-libhsail-rt
|
||||
|
||||
check-target-libhsail-rt:
|
||||
@: $(MAKE); $(unstage)
|
||||
@r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(TARGET_FLAGS_TO_PASS) check)
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: install-target-libhsail-rt maybe-install-target-libhsail-rt
|
||||
maybe-install-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-install-target-libhsail-rt: install-target-libhsail-rt
|
||||
|
||||
install-target-libhsail-rt: installdirs
|
||||
@: $(MAKE); $(unstage)
|
||||
@r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(TARGET_FLAGS_TO_PASS) install)
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: install-strip-target-libhsail-rt maybe-install-strip-target-libhsail-rt
|
||||
maybe-install-strip-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-install-strip-target-libhsail-rt: install-strip-target-libhsail-rt
|
||||
|
||||
install-strip-target-libhsail-rt: installdirs
|
||||
@: $(MAKE); $(unstage)
|
||||
@r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(TARGET_FLAGS_TO_PASS) install-strip)
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
# Other targets (info, dvi, pdf, etc.)
|
||||
|
||||
.PHONY: maybe-info-target-libhsail-rt info-target-libhsail-rt
|
||||
maybe-info-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-info-target-libhsail-rt: info-target-libhsail-rt
|
||||
|
||||
info-target-libhsail-rt: \
|
||||
configure-target-libhsail-rt
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing info in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
info) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-dvi-target-libhsail-rt dvi-target-libhsail-rt
|
||||
maybe-dvi-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-dvi-target-libhsail-rt: dvi-target-libhsail-rt
|
||||
|
||||
dvi-target-libhsail-rt: \
|
||||
configure-target-libhsail-rt
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing dvi in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
dvi) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-pdf-target-libhsail-rt pdf-target-libhsail-rt
|
||||
maybe-pdf-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-pdf-target-libhsail-rt: pdf-target-libhsail-rt
|
||||
|
||||
pdf-target-libhsail-rt: \
|
||||
configure-target-libhsail-rt
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing pdf in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
pdf) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-html-target-libhsail-rt html-target-libhsail-rt
|
||||
maybe-html-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-html-target-libhsail-rt: html-target-libhsail-rt
|
||||
|
||||
html-target-libhsail-rt: \
|
||||
configure-target-libhsail-rt
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing html in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
html) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-TAGS-target-libhsail-rt TAGS-target-libhsail-rt
|
||||
maybe-TAGS-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-TAGS-target-libhsail-rt: TAGS-target-libhsail-rt
|
||||
|
||||
TAGS-target-libhsail-rt: \
|
||||
configure-target-libhsail-rt
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing TAGS in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
TAGS) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-install-info-target-libhsail-rt install-info-target-libhsail-rt
|
||||
maybe-install-info-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-install-info-target-libhsail-rt: install-info-target-libhsail-rt
|
||||
|
||||
install-info-target-libhsail-rt: \
|
||||
configure-target-libhsail-rt \
|
||||
info-target-libhsail-rt
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing install-info in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
install-info) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-install-pdf-target-libhsail-rt install-pdf-target-libhsail-rt
|
||||
maybe-install-pdf-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-install-pdf-target-libhsail-rt: install-pdf-target-libhsail-rt
|
||||
|
||||
install-pdf-target-libhsail-rt: \
|
||||
configure-target-libhsail-rt \
|
||||
pdf-target-libhsail-rt
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing install-pdf in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
install-pdf) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-install-html-target-libhsail-rt install-html-target-libhsail-rt
|
||||
maybe-install-html-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-install-html-target-libhsail-rt: install-html-target-libhsail-rt
|
||||
|
||||
install-html-target-libhsail-rt: \
|
||||
configure-target-libhsail-rt \
|
||||
html-target-libhsail-rt
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing install-html in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
install-html) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-installcheck-target-libhsail-rt installcheck-target-libhsail-rt
|
||||
maybe-installcheck-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-installcheck-target-libhsail-rt: installcheck-target-libhsail-rt
|
||||
|
||||
installcheck-target-libhsail-rt: \
|
||||
configure-target-libhsail-rt
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing installcheck in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
installcheck) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-mostlyclean-target-libhsail-rt mostlyclean-target-libhsail-rt
|
||||
maybe-mostlyclean-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-mostlyclean-target-libhsail-rt: mostlyclean-target-libhsail-rt
|
||||
|
||||
mostlyclean-target-libhsail-rt:
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing mostlyclean in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
mostlyclean) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-clean-target-libhsail-rt clean-target-libhsail-rt
|
||||
maybe-clean-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-clean-target-libhsail-rt: clean-target-libhsail-rt
|
||||
|
||||
clean-target-libhsail-rt:
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing clean in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
clean) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-distclean-target-libhsail-rt distclean-target-libhsail-rt
|
||||
maybe-distclean-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-distclean-target-libhsail-rt: distclean-target-libhsail-rt
|
||||
|
||||
distclean-target-libhsail-rt:
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing distclean in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
distclean) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
.PHONY: maybe-maintainer-clean-target-libhsail-rt maintainer-clean-target-libhsail-rt
|
||||
maybe-maintainer-clean-target-libhsail-rt:
|
||||
@if target-libhsail-rt
|
||||
maybe-maintainer-clean-target-libhsail-rt: maintainer-clean-target-libhsail-rt
|
||||
|
||||
maintainer-clean-target-libhsail-rt:
|
||||
@: $(MAKE); $(unstage)
|
||||
@[ -f $(TARGET_SUBDIR)/libhsail-rt/Makefile ] || exit 0; \
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(NORMAL_TARGET_EXPORTS) \
|
||||
echo "Doing maintainer-clean in $(TARGET_SUBDIR)/libhsail-rt"; \
|
||||
for flag in $(EXTRA_TARGET_FLAGS); do \
|
||||
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
|
||||
done; \
|
||||
(cd $(TARGET_SUBDIR)/libhsail-rt && \
|
||||
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
|
||||
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
|
||||
"RANLIB=$${RANLIB}" \
|
||||
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
|
||||
maintainer-clean) \
|
||||
|| exit 1
|
||||
|
||||
@endif target-libhsail-rt
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.PHONY: configure-target-libtermcap maybe-configure-target-libtermcap
|
||||
maybe-configure-target-libtermcap:
|
||||
@if gcc-bootstrap
|
||||
|
@ -51382,6 +51858,14 @@ check-gcc-go:
|
|||
(cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-go);
|
||||
check-go: check-gcc-go check-target-libgo
|
||||
|
||||
.PHONY: check-gcc-brig check-brig
|
||||
check-gcc-brig:
|
||||
r=`${PWD_COMMAND}`; export r; \
|
||||
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
|
||||
$(HOST_EXPORTS) \
|
||||
(cd gcc && $(MAKE) $(GCC_FLAGS_TO_PASS) check-brig);
|
||||
check-brig: check-gcc-brig check-target-libhsail-rt
|
||||
|
||||
|
||||
# The gcc part of install-no-fixedincludes, which relies on an intimate
|
||||
# knowledge of how a number of gcc internal targets (inter)operate. Delegate.
|
||||
|
@ -54259,6 +54743,7 @@ configure-target-libquadmath: stage_last
|
|||
configure-target-libgfortran: stage_last
|
||||
configure-target-libobjc: stage_last
|
||||
configure-target-libgo: stage_last
|
||||
configure-target-libhsail-rt: stage_last
|
||||
configure-target-libtermcap: stage_last
|
||||
configure-target-winsup: stage_last
|
||||
configure-target-libgloss: stage_last
|
||||
|
@ -54293,6 +54778,7 @@ configure-target-libquadmath: maybe-all-gcc
|
|||
configure-target-libgfortran: maybe-all-gcc
|
||||
configure-target-libobjc: maybe-all-gcc
|
||||
configure-target-libgo: maybe-all-gcc
|
||||
configure-target-libhsail-rt: maybe-all-gcc
|
||||
configure-target-libtermcap: maybe-all-gcc
|
||||
configure-target-winsup: maybe-all-gcc
|
||||
configure-target-libgloss: maybe-all-gcc
|
||||
|
@ -55445,6 +55931,7 @@ configure-target-libquadmath: maybe-all-target-libgcc
|
|||
configure-target-libgfortran: maybe-all-target-libgcc
|
||||
configure-target-libobjc: maybe-all-target-libgcc
|
||||
configure-target-libgo: maybe-all-target-libgcc
|
||||
configure-target-libhsail-rt: maybe-all-target-libgcc
|
||||
configure-target-libtermcap: maybe-all-target-libgcc
|
||||
configure-target-winsup: maybe-all-target-libgcc
|
||||
configure-target-libgloss: maybe-all-target-libgcc
|
||||
|
@ -55486,6 +55973,8 @@ configure-target-libobjc: maybe-all-target-newlib maybe-all-target-libgloss
|
|||
|
||||
configure-target-libgo: maybe-all-target-newlib maybe-all-target-libgloss
|
||||
|
||||
configure-target-libhsail-rt: maybe-all-target-newlib maybe-all-target-libgloss
|
||||
|
||||
configure-target-libtermcap: maybe-all-target-newlib maybe-all-target-libgloss
|
||||
|
||||
configure-target-winsup: maybe-all-target-newlib maybe-all-target-libgloss
|
||||
|
|
14
configure
vendored
14
configure
vendored
|
@ -2754,6 +2754,7 @@ target_libraries="target-libgcc \
|
|||
target-libgomp \
|
||||
target-libcilkrts \
|
||||
target-liboffloadmic \
|
||||
target-libhsail-rt \
|
||||
target-libatomic \
|
||||
target-libitm \
|
||||
target-libstdc++-v3 \
|
||||
|
@ -3482,6 +3483,19 @@ if test x$enable_libgo = x; then
|
|||
esac
|
||||
fi
|
||||
|
||||
# Disable the BRIG frontend and libhsail-rt on untested or known
|
||||
# broken systems. Currently it has been tested only on x86_64 Linux
|
||||
# of the upstream gcc targets. More targets shall be added after testing.
|
||||
case "${target}" in
|
||||
x86_64-*-linux*)
|
||||
;;
|
||||
*)
|
||||
unsupported_languages="$unsupported_languages brig"
|
||||
# This implicitly disables also target-libhsail-rt as it won't
|
||||
# get added to the build without BRIG FE.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Default libgloss CPU subdirectory.
|
||||
libgloss_dir="$target_cpu"
|
||||
|
||||
|
|
14
configure.ac
14
configure.ac
|
@ -152,6 +152,7 @@ target_libraries="target-libgcc \
|
|||
target-libgomp \
|
||||
target-libcilkrts \
|
||||
target-liboffloadmic \
|
||||
target-libhsail-rt \
|
||||
target-libatomic \
|
||||
target-libitm \
|
||||
target-libstdc++-v3 \
|
||||
|
@ -812,6 +813,19 @@ if test x$enable_libgo = x; then
|
|||
esac
|
||||
fi
|
||||
|
||||
# Disable the BRIG frontend and libhsail-rt on untested or known
|
||||
# broken systems. Currently it has been tested only on x86_64 Linux
|
||||
# of the upstream gcc targets. More targets shall be added after testing.
|
||||
case "${target}" in
|
||||
x86_64-*-linux*)
|
||||
;;
|
||||
*)
|
||||
unsupported_languages="$unsupported_languages brig"
|
||||
# This implicitly disables also target-libhsail-rt as it won't
|
||||
# get added to the build without BRIG FE.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Default libgloss CPU subdirectory.
|
||||
libgloss_dir="$target_cpu"
|
||||
|
||||
|
|
|
@ -1,3 +1,66 @@
|
|||
2017-01-24 Pekka Jääskeläinen <pekka@parmance.com>
|
||||
Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* brig-builtins.def: New file.
|
||||
* builtins.def (DEF_HSAIL_BUILTIN): New macro.
|
||||
(DEF_HSAIL_ATOMIC_BUILTIN): Likewise.
|
||||
(DEF_HSAIL_SAT_BUILTIN): Likewise.
|
||||
(DEF_HSAIL_INTR_BUILTIN): Likewise.
|
||||
(DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN): Likewise.
|
||||
* builtin-types.def (BT_INT8): New.
|
||||
(BT_INT16): Likewise.
|
||||
(BT_UINT8): Likewise.
|
||||
(BT_UINT16): Likewise.
|
||||
(BT_FN_ULONG): Likewise.
|
||||
(BT_FN_UINT_INT): Likewise.
|
||||
(BT_FN_UINT_ULONG): Likewise.
|
||||
(BT_FN_UINT_LONG): Likewise.
|
||||
(BT_FN_UINT_PTR): Likewise.
|
||||
(BT_FN_ULONG_PTR): Likewise.
|
||||
(BT_FN_INT8_FLOAT): Likewise.
|
||||
(BT_FN_INT16_FLOAT): Likewise.
|
||||
(BT_FN_UINT32_FLOAT): Likewise.
|
||||
(BT_FN_UINT16_FLOAT): Likewise.
|
||||
(BT_FN_UINT8_FLOAT): Likewise.
|
||||
(BT_FN_UINT64_FLOAT): Likewise.
|
||||
(BT_FN_UINT16_UINT32): Likewise.
|
||||
(BT_FN_UINT32_UINT16): Likewise.
|
||||
(BT_FN_UINT16_UINT16_UINT16): Likewise.
|
||||
(BT_FN_INT_PTR_INT): Likewise.
|
||||
(BT_FN_UINT_PTR_UINT): Likewise.
|
||||
(BT_FN_LONG_PTR_LONG): Likewise.
|
||||
(BT_FN_ULONG_PTR_ULONG): Likewise.
|
||||
(BT_FN_VOID_UINT64_UINT64): Likewise.
|
||||
(BT_FN_UINT8_UINT8_UINT8): Likewise.
|
||||
(BT_FN_INT8_INT8_INT8): Likewise.
|
||||
(BT_FN_INT16_INT16_INT16): Likewise.
|
||||
(BT_FN_INT_INT_INT): Likewise.
|
||||
(BT_FN_UINT_FLOAT_UINT): Likewise.
|
||||
(BT_FN_FLOAT_UINT_UINT): Likewise.
|
||||
(BT_FN_ULONG_UINT_UINT): Likewise.
|
||||
(BT_FN_ULONG_UINT_PTR): Likewise.
|
||||
(BT_FN_ULONG_ULONG_ULONG): Likewise.
|
||||
(BT_FN_UINT_UINT_UINT): Likewise.
|
||||
(BT_FN_VOID_UINT_PTR): Likewise.
|
||||
(BT_FN_UINT_UINT_PTR: Likewise.
|
||||
(BT_FN_UINT32_UINT64_PTR): Likewise.
|
||||
(BT_FN_INT_INT_UINT_UINT): Likewise.
|
||||
(BT_FN_UINT_UINT_UINT_UINT): Likewise.
|
||||
(BT_FN_UINT_UINT_UINT_PTR): Likewise.
|
||||
(BT_FN_UINT_ULONG_ULONG_UINT): Likewise.
|
||||
(BT_FN_ULONG_ULONG_ULONG_ULONG): Likewise.
|
||||
(BT_FN_LONG_LONG_UINT_UINT): Likewise.
|
||||
(BT_FN_ULONG_ULONG_UINT_UINT): Likewise.
|
||||
(BT_FN_VOID_UINT32_UINT64_PTR): Likewise.
|
||||
(BT_FN_VOID_UINT32_UINT32_PTR): Likewise.
|
||||
(BT_FN_UINT_UINT_UINT_UINT_UINT): Likewise.
|
||||
(BT_FN_UINT_FLOAT_FLOAT_FLOAT_FLOAT): Likewise.
|
||||
(BT_FN_ULONG_ULONG_ULONG_UINT_UINT): Likewise.
|
||||
* doc/frontends.texi: List BRIG FE.
|
||||
* doc/install.texi (Testing): Add BRIG tesring requirements.
|
||||
* doc/invoke.texi (Overall Options): Mention BRIG.
|
||||
* doc/standards.texi (Standards): Doucment BRIG HSA version.
|
||||
|
||||
2017-01-24 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR translation/79208
|
||||
|
|
659
gcc/brig-builtins.def
Normal file
659
gcc/brig-builtins.def
Normal file
|
@ -0,0 +1,659 @@
|
|||
/* This file contains the definitions and documentation for the
|
||||
HSAIL builtins used in the GNU compiler.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* Following builtins are used by the BRIG (the binary representation of
|
||||
HSAIL) frontend. Software implementations are available in libhsail-rt.
|
||||
Use leading double underscore in the name to avoid name space clashes
|
||||
with kernel program symbols in case the builtin is implemented as
|
||||
a function call. */
|
||||
|
||||
/* Work-item ID related builtins are not constant in the work-group function
|
||||
mode (each WI has a different return value). */
|
||||
|
||||
#ifndef DEF_HSAIL_BUILTIN
|
||||
#define DEF_HSAIL_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, \
|
||||
NAME, TYPE, ATTRS)
|
||||
#endif
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMABSID, BRIG_OPCODE_WORKITEMABSID,
|
||||
BRIG_TYPE_U32, "__hsail_workitemabsid", BT_FN_UINT_UINT_PTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_GRIDSIZE, BRIG_OPCODE_GRIDSIZE,
|
||||
BRIG_TYPE_U32, "__hsail_gridsize", BT_FN_UINT_UINT_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMFLATABSID_U32,
|
||||
BRIG_OPCODE_WORKITEMFLATABSID, BRIG_TYPE_U32,
|
||||
"__hsail_workitemflatabsid_u32", BT_FN_UINT_PTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMFLATABSID_U64,
|
||||
BRIG_OPCODE_WORKITEMFLATABSID, BRIG_TYPE_U64,
|
||||
"__hsail_workitemflatabsid_u64", BT_FN_ULONG_PTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMFLATID, BRIG_OPCODE_WORKITEMFLATID,
|
||||
BRIG_TYPE_U32, "__hsail_workitemflatid", BT_FN_UINT_PTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMID, BRIG_OPCODE_WORKITEMID,
|
||||
BRIG_TYPE_U32, "__hsail_workitemid", BT_FN_UINT_UINT_PTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKGROUPID, BRIG_OPCODE_WORKGROUPID,
|
||||
BRIG_TYPE_U32, "__hsail_workgroupid", BT_FN_UINT_UINT_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CURRENTWORKITEMFLATID,
|
||||
BRIG_OPCODE_CURRENTWORKITEMFLATID,
|
||||
BRIG_TYPE_U32, "__hsail_currentworkitemflatid",
|
||||
BT_FN_UINT_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKITEMABSID_U64, BRIG_OPCODE_WORKITEMABSID,
|
||||
BRIG_TYPE_U64, "__hsail_workitemabsid_u64",
|
||||
BT_FN_ULONG_UINT_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_PACKETID, BRIG_OPCODE_PACKETID,
|
||||
BRIG_TYPE_U64, "__hsail_packetid", BT_FN_ULONG_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_PACKETCOMPLETIONSIG_SIG64,
|
||||
BRIG_OPCODE_PACKETCOMPLETIONSIG, BRIG_TYPE_SIG64,
|
||||
"__hsail_packetcompletionsig_sig64", BT_FN_ULONG_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_PACKETCOMPLETIONSIG_SIG32,
|
||||
BRIG_OPCODE_PACKETCOMPLETIONSIG, BRIG_TYPE_SIG32,
|
||||
"__hsail_packetcompletionsig_sig32", BT_FN_UINT_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CURRENTWORKGROUPSIZE,
|
||||
BRIG_OPCODE_CURRENTWORKGROUPSIZE, BRIG_TYPE_U32,
|
||||
"__hsail_currentworkgroupsize", BT_FN_UINT_UINT_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WORKGROUPSIZE, BRIG_OPCODE_WORKGROUPSIZE,
|
||||
BRIG_TYPE_U32, "__hsail_workgroupsize", BT_FN_UINT_UINT_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_DIM, BRIG_OPCODE_DIM,
|
||||
BRIG_TYPE_U32, "__hsail_dim", BT_FN_UINT_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_GRIDGROUPS, BRIG_OPCODE_GRIDGROUPS,
|
||||
BRIG_TYPE_U32, "__hsail_gridgroups", BT_FN_UINT_UINT_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITEXTRACT_S32, BRIG_OPCODE_BITEXTRACT,
|
||||
BRIG_TYPE_S32, "__hsail_bitextract_s32",
|
||||
BT_FN_INT_INT_UINT_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITEXTRACT_U32, BRIG_OPCODE_BITEXTRACT,
|
||||
BRIG_TYPE_U32, "__hsail_bitextract_u32",
|
||||
BT_FN_UINT_UINT_UINT_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITEXTRACT_S64, BRIG_OPCODE_BITEXTRACT,
|
||||
BRIG_TYPE_S64, "__hsail_bitextract_s64",
|
||||
BT_FN_LONG_LONG_UINT_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITEXTRACT_U64, BRIG_OPCODE_BITEXTRACT,
|
||||
BRIG_TYPE_U64, "__hsail_bitextract_u64",
|
||||
BT_FN_ULONG_ULONG_UINT_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITINSERT_U32, BRIG_OPCODE_BITINSERT,
|
||||
BRIG_TYPE_U32, "__hsail_bitinsert_u32",
|
||||
BT_FN_UINT_UINT_UINT_UINT_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITINSERT_U64, BRIG_OPCODE_BITINSERT,
|
||||
BRIG_TYPE_U64, "__hsail_bitinsert_u64",
|
||||
BT_FN_ULONG_ULONG_ULONG_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITMASK_B32, BRIG_OPCODE_BITMASK,
|
||||
BRIG_TYPE_B32, "__hsail_bitmask_u32", BT_FN_UINT_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITMASK_B64, BRIG_OPCODE_BITMASK,
|
||||
BRIG_TYPE_B64, "__hsail_bitmask_u64", BT_FN_ULONG_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITREV_B32, BRIG_OPCODE_BITREV,
|
||||
BRIG_TYPE_B32, "__hsail_bitrev_u32", BT_FN_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITREV_B64, BRIG_OPCODE_BITREV,
|
||||
BRIG_TYPE_B64, "__hsail_bitrev_u64", BT_FN_ULONG_ULONG,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITSELECT_B32, BRIG_OPCODE_BITSELECT,
|
||||
BRIG_TYPE_B32, "__hsail_bitselect_u32",
|
||||
BT_FN_UINT_UINT_UINT_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITSELECT_U64, BRIG_OPCODE_BITSELECT,
|
||||
BRIG_TYPE_B64, "__hsail_bitselect_u64",
|
||||
BT_FN_ULONG_ULONG_ULONG_ULONG, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FIRSTBIT_U32, BRIG_OPCODE_FIRSTBIT,
|
||||
BRIG_TYPE_U32, "__hsail_firstbit_u32", BT_FN_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FIRSTBIT_S32, BRIG_OPCODE_FIRSTBIT,
|
||||
BRIG_TYPE_S32, "__hsail_firstbit_s32", BT_FN_UINT_INT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FIRSTBIT_U64, BRIG_OPCODE_FIRSTBIT,
|
||||
BRIG_TYPE_U64, "__hsail_firstbit_u64", BT_FN_UINT_ULONG,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FIRSTBIT_S64, BRIG_OPCODE_FIRSTBIT,
|
||||
BRIG_TYPE_S64, "__hsail_firstbit_s64", BT_FN_UINT_LONG,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LASTBIT_U32, BRIG_OPCODE_LASTBIT,
|
||||
BRIG_TYPE_U32, "__hsail_lastbit_u32", BT_FN_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LASTBIT_U64, BRIG_OPCODE_LASTBIT,
|
||||
BRIG_TYPE_U64, "__hsail_lastbit_u64", BT_FN_UINT_ULONG,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BORROW_U32, BRIG_OPCODE_BORROW,
|
||||
BRIG_TYPE_U32, "__hsail_borrow_u32", BT_FN_UINT_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BORROW_U64, BRIG_OPCODE_BORROW,
|
||||
BRIG_TYPE_U64, "__hsail_borrow_u64", BT_FN_ULONG_ULONG_ULONG,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CARRY_U32, BRIG_OPCODE_CARRY,
|
||||
BRIG_TYPE_U32, "__hsail_carry_u32", BT_FN_UINT_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CARRY_U64, BRIG_OPCODE_CARRY,
|
||||
BRIG_TYPE_U64, "__hsail_carry_u64", BT_FN_ULONG_ULONG_ULONG,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_REM_S32, BRIG_OPCODE_REM,
|
||||
BRIG_TYPE_S32, "__hsail_rem_s32", BT_FN_INT_INT_INT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_REM_S64, BRIG_OPCODE_REM,
|
||||
BRIG_TYPE_S64, "__hsail_rem_s64", BT_FN_LONG_LONG_LONG,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_MIN_F32, BRIG_OPCODE_MIN,
|
||||
BRIG_TYPE_F32, "__hsail_min_f32", BT_FN_FLOAT_FLOAT_FLOAT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_MAX_F32, BRIG_OPCODE_MAX,
|
||||
BRIG_TYPE_F32, "__hsail_max_f32", BT_FN_FLOAT_FLOAT_FLOAT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_MIN_F64, BRIG_OPCODE_MIN,
|
||||
BRIG_TYPE_F64, "__hsail_min_f64", BT_FN_DOUBLE_DOUBLE_DOUBLE,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_MAX_F64, BRIG_OPCODE_MAX,
|
||||
BRIG_TYPE_F64, "__hsail_max_f64", BT_FN_DOUBLE_DOUBLE_DOUBLE,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CLASS_F32, BRIG_OPCODE_CLASS,
|
||||
BRIG_TYPE_F32, "__hsail_class_f32", BT_FN_UINT_FLOAT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CLASS_F32_F16, BRIG_OPCODE_CLASS,
|
||||
BRIG_TYPE_F16, "__hsail_class_f32_f16", BT_FN_UINT_FLOAT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FRACT_F32, BRIG_OPCODE_FRACT,
|
||||
BRIG_TYPE_F32, "__hsail_fract_f32", BT_FN_FLOAT_FLOAT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_FRACT_F64, BRIG_OPCODE_FRACT,
|
||||
BRIG_TYPE_F64, "__hsail_fract_f64", BT_FN_DOUBLE_DOUBLE,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BARRIER, BRIG_OPCODE_BARRIER,
|
||||
BRIG_TYPE_NONE, "__hsail_barrier", BT_FN_VOID_PTR,
|
||||
ATTR_NOTHROW_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_INITFBAR, BRIG_OPCODE_INITFBAR,
|
||||
BRIG_TYPE_NONE, "__hsail_initfbar", BT_FN_VOID_UINT_PTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_JOINFBAR, BRIG_OPCODE_JOINFBAR,
|
||||
BRIG_TYPE_NONE, "__hsail_joinfbar", BT_FN_VOID_UINT_PTR,
|
||||
ATTR_NOTHROW_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_WAITFBAR, BRIG_OPCODE_WAITFBAR,
|
||||
BRIG_TYPE_NONE, "__hsail_waitfbar", BT_FN_VOID_UINT_PTR,
|
||||
ATTR_NOTHROW_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_ARRIVEFBAR, BRIG_OPCODE_ARRIVEFBAR,
|
||||
BRIG_TYPE_NONE, "__hsail_arrivefbar", BT_FN_VOID_UINT_PTR,
|
||||
ATTR_NOTHROW_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LEAVEFBAR, BRIG_OPCODE_LEAVEFBAR,
|
||||
BRIG_TYPE_NONE, "__hsail_leavefbar", BT_FN_VOID_UINT_PTR,
|
||||
ATTR_NOTHROW_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_RELEASEFBAR, BRIG_OPCODE_RELEASEFBAR,
|
||||
BRIG_TYPE_NONE, "__hsail_releasefbar", BT_FN_VOID_UINT_PTR,
|
||||
ATTR_NOTHROW_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BITALIGN, BRIG_OPCODE_BITALIGN,
|
||||
BRIG_TYPE_B32, "__hsail_bitalign",
|
||||
BT_FN_UINT_ULONG_ULONG_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_BYTEALIGN, BRIG_OPCODE_BYTEALIGN,
|
||||
BRIG_TYPE_B32, "__hsail_bytealign",
|
||||
BT_FN_UINT_ULONG_ULONG_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LERP, BRIG_OPCODE_LERP,
|
||||
BRIG_TYPE_U8X4, "__hsail_lerp", BT_FN_UINT_UINT_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_PACKCVT, BRIG_OPCODE_PACKCVT,
|
||||
BRIG_TYPE_U8X4, "__hsail_packcvt",
|
||||
BT_FN_UINT_FLOAT_FLOAT_FLOAT_FLOAT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_UNPACKCVT, BRIG_OPCODE_UNPACKCVT,
|
||||
BRIG_TYPE_F32, "__hsail_unpackcvt", BT_FN_FLOAT_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SAD_U16X2, BRIG_OPCODE_SAD,
|
||||
BRIG_TYPE_U16X2, "__hsail_sad_u16x2",
|
||||
BT_FN_UINT_UINT_UINT_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SAD_U32, BRIG_OPCODE_SAD,
|
||||
BRIG_TYPE_U32, "__hsail_sad_u32", BT_FN_UINT_UINT_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SAD_U8X4, BRIG_OPCODE_SAD,
|
||||
BRIG_TYPE_U8X4, "__hsail_sad_u8x4", BT_FN_UINT_UINT_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SADHI_U8X4, BRIG_OPCODE_SADHI,
|
||||
BRIG_TYPE_U16X2, "__hsail_sadhi_u16x2_u8x4",
|
||||
BT_FN_UINT_UINT_UINT_UINT,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CLOCK, BRIG_OPCODE_CLOCK,
|
||||
BRIG_TYPE_U64, "__hsail_clock", BT_FN_ULONG,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CUID, BRIG_OPCODE_CUID,
|
||||
BRIG_TYPE_U32, "__hsail_cuid", BT_FN_UINT_PTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_MAXCUID, BRIG_OPCODE_MAXCUID,
|
||||
BRIG_TYPE_U32, "__hsail_maxcuid", BT_FN_UINT_PTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_DEBUGTRAP, BRIG_OPCODE_DEBUGTRAP,
|
||||
BRIG_TYPE_U32, "__hsail_debugtrap", BT_FN_VOID_UINT_PTR,
|
||||
ATTR_NORETURN_NOTHROW_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_GROUPBASEPTR, BRIG_OPCODE_GROUPBASEPTR,
|
||||
BRIG_TYPE_U32, "__hsail_groupbaseptr", BT_FN_UINT_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_KERNARGBASEPTR_U64,
|
||||
BRIG_OPCODE_KERNARGBASEPTR, BRIG_TYPE_U64,
|
||||
"__hsail_kernargbaseptr_u64", BT_FN_ULONG_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_KERNARGBASEPTR_U32,
|
||||
BRIG_OPCODE_KERNARGBASEPTR, BRIG_TYPE_U32,
|
||||
"__hsail_kernargbaseptr_u32", BT_FN_UINT_PTR,
|
||||
ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_ALLOCA, BRIG_OPCODE_ALLOCA,
|
||||
BRIG_TYPE_U32, "__hsail_alloca", BT_FN_UINT_UINT_UINT_PTR,
|
||||
ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LDQUEUEWRITEINDEX,
|
||||
BRIG_OPCODE_LDQUEUEWRITEINDEX,
|
||||
BRIG_TYPE_U64, "__hsail_ldqueuewriteindex",
|
||||
BT_FN_ULONG_ULONG, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_LDQUEUEREADINDEX,
|
||||
BRIG_OPCODE_LDQUEUEREADINDEX,
|
||||
BRIG_TYPE_U64, "__hsail_ldqueuereadindex",
|
||||
BT_FN_ULONG_ULONG, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_STQUEUEWRITEINDEX,
|
||||
BRIG_OPCODE_STQUEUEWRITEINDEX,
|
||||
BRIG_TYPE_U64, "__hsail_stqueuewriteindex",
|
||||
BT_FN_VOID_UINT64_UINT64, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_STQUEUEREADINDEX,
|
||||
BRIG_OPCODE_STQUEUEREADINDEX,
|
||||
BRIG_TYPE_U64, "__hsail_stqueuereadindex",
|
||||
BT_FN_VOID_UINT64_UINT64, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_ADDQUEUEWRITEINDEX,
|
||||
BRIG_OPCODE_ADDQUEUEWRITEINDEX,
|
||||
BRIG_TYPE_U64, "__hsail_addqueuewriteindex",
|
||||
BT_FN_ULONG_ULONG_ULONG, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_CASQUEUEWRITEINDEX,
|
||||
BRIG_OPCODE_CASQUEUEWRITEINDEX,
|
||||
BRIG_TYPE_U64, "__hsail_casqueuewriteindex",
|
||||
BT_FN_ULONG_ULONG_ULONG_ULONG, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SEGMENTP_GLOBAL,
|
||||
BRIG_OPCODE_SEGMENTP,
|
||||
BRIG_TYPE_U32, "__hsail_segmentp_global",
|
||||
BT_FN_UINT32_UINT64_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SEGMENTP_GROUP,
|
||||
BRIG_OPCODE_SEGMENTP,
|
||||
BRIG_TYPE_U32, "__hsail_segmentp_group",
|
||||
BT_FN_UINT32_UINT64_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_BUILTIN (BUILT_IN_HSAIL_SEGMENTP_PRIVATE,
|
||||
BRIG_OPCODE_SEGMENTP,
|
||||
BRIG_TYPE_U32, "__hsail_segmentp_private",
|
||||
BT_FN_UINT32_UINT64_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
#ifndef DEF_HSAIL_ATOMIC_BUILTIN
|
||||
#define DEF_HSAIL_ATOMIC_BUILTIN(ENUM, ATOMIC_OPCODE, HSAIL_TYPE, \
|
||||
NAME, TYPE, ATTRS)
|
||||
#endif
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MIN_S32, BRIG_ATOMIC_MIN,
|
||||
BRIG_TYPE_S32, "__hsail_atomic_min_s32",
|
||||
BT_FN_INT_PTR_INT, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MIN_S64, BRIG_ATOMIC_MIN,
|
||||
BRIG_TYPE_S64, "__hsail_atomic_min_s64",
|
||||
BT_FN_LONG_PTR_LONG, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MIN_U32, BRIG_ATOMIC_MIN,
|
||||
BRIG_TYPE_U32, "__hsail_atomic_min_u32",
|
||||
BT_FN_UINT_PTR_UINT, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MIN_U64, BRIG_ATOMIC_MIN,
|
||||
BRIG_TYPE_U64, "__hsail_atomic_min_u64",
|
||||
BT_FN_ULONG_PTR_ULONG, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MAX_S32, BRIG_ATOMIC_MAX,
|
||||
BRIG_TYPE_S32, "__hsail_atomic_max_s32",
|
||||
BT_FN_INT_PTR_INT, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MAX_S64, BRIG_ATOMIC_MAX,
|
||||
BRIG_TYPE_S64, "__hsail_atomic_max_s64",
|
||||
BT_FN_LONG_PTR_LONG, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MAX_U32, BRIG_ATOMIC_MAX,
|
||||
BRIG_TYPE_U32, "__hsail_atomic_max_u32",
|
||||
BT_FN_UINT_PTR_UINT, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_MAX_U64, BRIG_ATOMIC_MAX,
|
||||
BRIG_TYPE_U64, "__hsail_atomic_max_u64",
|
||||
BT_FN_ULONG_PTR_ULONG, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_WRAPDEC_U32,
|
||||
BRIG_ATOMIC_WRAPDEC, BRIG_TYPE_U32,
|
||||
"__hsail_atomic_wrapdec_u32",
|
||||
BT_FN_UINT_PTR_UINT, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_WRAPDEC_U64,
|
||||
BRIG_ATOMIC_WRAPDEC, BRIG_TYPE_U64,
|
||||
"__hsail_atomic_wrapdec_u64",
|
||||
BT_FN_ULONG_PTR_ULONG, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_WRAPINC_U32,
|
||||
BRIG_ATOMIC_WRAPINC, BRIG_TYPE_U32,
|
||||
"__hsail_atomic_wrapinc_u32",
|
||||
BT_FN_UINT_PTR_UINT, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_ATOMIC_BUILTIN (BUILT_IN_HSAIL_ATOMIC_WRAPINC_U64,
|
||||
BRIG_ATOMIC_WRAPINC, BRIG_TYPE_U64,
|
||||
"__hsail_atomic_wrapinc_u64",
|
||||
BT_FN_ULONG_PTR_ULONG, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
#ifndef DEF_HSAIL_SAT_BUILTIN
|
||||
#define DEF_HSAIL_SAT_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, \
|
||||
NAME, TYPE, ATTRS)
|
||||
#endif
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_U64, BRIG_OPCODE_ADD,
|
||||
BRIG_TYPE_U64, "__hsail_sat_add_u64",
|
||||
BT_FN_ULONG_ULONG_ULONG, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_S64, BRIG_OPCODE_ADD,
|
||||
BRIG_TYPE_S64, "__hsail_sat_add_s64",
|
||||
BT_FN_LONG_LONG_LONG, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_U32, BRIG_OPCODE_ADD,
|
||||
BRIG_TYPE_U32, "__hsail_sat_add_u32",
|
||||
BT_FN_UINT_UINT_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_S32, BRIG_OPCODE_ADD,
|
||||
BRIG_TYPE_S32, "__hsail_sat_add_s32",
|
||||
BT_FN_INT_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_U16, BRIG_OPCODE_ADD,
|
||||
BRIG_TYPE_U16, "__hsail_sat_add_u16",
|
||||
BT_FN_UINT16_UINT16_UINT16, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_S16, BRIG_OPCODE_ADD,
|
||||
BRIG_TYPE_S16, "__hsail_sat_add_s16",
|
||||
BT_FN_INT16_INT16_INT16, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_U8, BRIG_OPCODE_ADD,
|
||||
BRIG_TYPE_U8, "__hsail_sat_add_u8",
|
||||
BT_FN_UINT8_UINT8_UINT8, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_ADD_S8, BRIG_OPCODE_ADD,
|
||||
BRIG_TYPE_S8, "__hsail_sat_add_s8",
|
||||
BT_FN_INT8_INT8_INT8, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_U64, BRIG_OPCODE_SUB,
|
||||
BRIG_TYPE_U64, "__hsail_sat_sub_u64",
|
||||
BT_FN_ULONG_ULONG_ULONG, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_S64, BRIG_OPCODE_SUB,
|
||||
BRIG_TYPE_S64, "__hsail_sat_sub_s64",
|
||||
BT_FN_LONG_LONG_LONG, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_U32, BRIG_OPCODE_SUB,
|
||||
BRIG_TYPE_U32, "__hsail_sat_sub_u32",
|
||||
BT_FN_UINT_UINT_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_S32, BRIG_OPCODE_SUB,
|
||||
BRIG_TYPE_S32, "__hsail_sat_sub_s32",
|
||||
BT_FN_INT_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_U16, BRIG_OPCODE_SUB,
|
||||
BRIG_TYPE_U16, "__hsail_sat_sub_u16",
|
||||
BT_FN_UINT16_UINT16_UINT16, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_S16, BRIG_OPCODE_SUB,
|
||||
BRIG_TYPE_S16, "__hsail_sat_sub_s16",
|
||||
BT_FN_INT16_INT16_INT16, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_U8, BRIG_OPCODE_SUB,
|
||||
BRIG_TYPE_U8, "__hsail_sat_sub_u8",
|
||||
BT_FN_UINT8_UINT8_UINT8, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_SUB_S8, BRIG_OPCODE_SUB,
|
||||
BRIG_TYPE_S8, "__hsail_sat_sub_s8",
|
||||
BT_FN_INT8_INT8_INT8, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_U64, BRIG_OPCODE_MUL,
|
||||
BRIG_TYPE_U64, "__hsail_sat_mul_u64",
|
||||
BT_FN_ULONG_ULONG_ULONG, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_S64, BRIG_OPCODE_MUL,
|
||||
BRIG_TYPE_S64, "__hsail_sat_mul_s64",
|
||||
BT_FN_LONG_LONG_LONG, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_U32, BRIG_OPCODE_MUL,
|
||||
BRIG_TYPE_U32, "__hsail_sat_mul_u32",
|
||||
BT_FN_UINT_UINT_UINT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_S32, BRIG_OPCODE_MUL,
|
||||
BRIG_TYPE_S32, "__hsail_sat_mul_s32",
|
||||
BT_FN_INT_INT_INT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_U16, BRIG_OPCODE_MUL,
|
||||
BRIG_TYPE_U16, "__hsail_sat_mul_u16",
|
||||
BT_FN_UINT16_UINT16_UINT16, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_S16, BRIG_OPCODE_MUL,
|
||||
BRIG_TYPE_S16, "__hsail_sat_mul_s16",
|
||||
BT_FN_INT16_INT16_INT16, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_U8, BRIG_OPCODE_MUL,
|
||||
BRIG_TYPE_U8, "__hsail_sat_mul_u8",
|
||||
BT_FN_UINT8_UINT8_UINT8, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_SAT_BUILTIN (BUILT_IN_HSAIL_SAT_MUL_S8, BRIG_OPCODE_MUL,
|
||||
BRIG_TYPE_S8, "__hsail_sat_mul_s8",
|
||||
BT_FN_INT8_INT8_INT8, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
#ifndef DEF_HSAIL_INTR_BUILTIN
|
||||
#define DEF_HSAIL_INTR_BUILTIN(ENUM, NAME, TYPE, ATTRS)
|
||||
#endif
|
||||
|
||||
DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_FTZ_F32_F16, "__hsail_ftz_f32_f16",
|
||||
BT_FN_FLOAT_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_FTZ_F32, "__hsail_ftz_f32",
|
||||
BT_FN_FLOAT_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_FTZ_F64, "__hsail_ftz_f64",
|
||||
BT_FN_DOUBLE_DOUBLE, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_PUSH_FRAME, "__hsail_alloca_push_frame",
|
||||
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_POP_FRAME, "__hsail_alloca_pop_frame",
|
||||
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_SETWORKITEMID, "__hsail_setworkitemid",
|
||||
BT_FN_VOID_UINT32_UINT32_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_LAUNCH_WG_FUNC,
|
||||
"__hsail_launch_wg_function",
|
||||
BT_FN_VOID_PTR_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_LAUNCH_KERNEL,
|
||||
"__hsail_launch_kernel",
|
||||
BT_FN_VOID_PTR_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_F32_TO_F16, "__hsail_f32_to_f16",
|
||||
BT_FN_UINT16_UINT32, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_INTR_BUILTIN (BUILT_IN_HSAIL_F16_TO_F32, "__hsail_f16_to_f32",
|
||||
BT_FN_UINT32_UINT16, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
#ifndef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN
|
||||
#define DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN(ENUM, HSAIL_DEST_TYPE, HSAIL_SRC_TYPE, \
|
||||
NAME, TYPE, ATTRS)
|
||||
#endif
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U8_F32,
|
||||
BRIG_TYPE_U8, BRIG_TYPE_F32,
|
||||
"__hsail_cvt_zeroi_sat_u8_f32",
|
||||
BT_FN_UINT8_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S8_F32,
|
||||
BRIG_TYPE_S8, BRIG_TYPE_F32,
|
||||
"__hsail_cvt_zeroi_sat_s8_f32",
|
||||
BT_FN_INT8_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U16_F32,
|
||||
BRIG_TYPE_U16, BRIG_TYPE_F32,
|
||||
"__hsail_cvt_zeroi_sat_u16_f32",
|
||||
BT_FN_UINT16_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S16_F32,
|
||||
BRIG_TYPE_S16, BRIG_TYPE_F32,
|
||||
"__hsail_cvt_zeroi_sat_s16_f32",
|
||||
BT_FN_INT16_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U32_F32,
|
||||
BRIG_TYPE_U32, BRIG_TYPE_F32,
|
||||
"__hsail_cvt_zeroi_sat_u32_f32",
|
||||
BT_FN_UINT32_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S32_F32,
|
||||
BRIG_TYPE_S32, BRIG_TYPE_F32,
|
||||
"__hsail_cvt_zeroi_sat_s32_f32",
|
||||
BT_FN_INT_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U64_F32,
|
||||
BRIG_TYPE_U64, BRIG_TYPE_F32,
|
||||
"__hsail_cvt_zeroi_sat_u64_f32",
|
||||
BT_FN_UINT64_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S64_F32,
|
||||
BRIG_TYPE_S64, BRIG_TYPE_F32,
|
||||
"__hsail_cvt_zeroi_sat_s64_f32",
|
||||
BT_FN_LONG_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U8_F64,
|
||||
BRIG_TYPE_U8, BRIG_TYPE_F64,
|
||||
"__hsail_cvt_zeroi_sat_u8_f64",
|
||||
BT_FN_UINT8_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S8_F64,
|
||||
BRIG_TYPE_S8, BRIG_TYPE_F64,
|
||||
"__hsail_cvt_zeroi_sat_s8_f64",
|
||||
BT_FN_INT8_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U16_F64,
|
||||
BRIG_TYPE_U16, BRIG_TYPE_F64,
|
||||
"__hsail_cvt_zeroi_sat_u16_f64",
|
||||
BT_FN_UINT16_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S16_F64,
|
||||
BRIG_TYPE_S16, BRIG_TYPE_F64,
|
||||
"__hsail_cvt_zeroi_sat_s16_f64",
|
||||
BT_FN_INT16_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U32_F64,
|
||||
BRIG_TYPE_U32, BRIG_TYPE_F64,
|
||||
"__hsail_cvt_zeroi_sat_u32_f64",
|
||||
BT_FN_UINT32_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S32_F64,
|
||||
BRIG_TYPE_S32, BRIG_TYPE_F64,
|
||||
"__hsail_cvt_zeroi_sat_s32_f64",
|
||||
BT_FN_INT_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_U64_F64,
|
||||
BRIG_TYPE_U64, BRIG_TYPE_F64,
|
||||
"__hsail_cvt_zeroi_sat_u64_f64",
|
||||
BT_FN_UINT64_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
||||
|
||||
DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN (BUILT_IN_HSAIL_CVT_ZEROI_SAT_S64_F64,
|
||||
BRIG_TYPE_S64, BRIG_TYPE_F64,
|
||||
"__hsail_cvt_zeroi_sat_s64_f64",
|
||||
BT_FN_LONG_FLOAT, ATTR_PURE_NOTHROW_LEAF_LIST)
|
42
gcc/brig/ChangeLog
Normal file
42
gcc/brig/ChangeLog
Normal file
|
@ -0,0 +1,42 @@
|
|||
2017-01-24 Pekka Jääskeläinen <pekka@parmance.com>
|
||||
Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* Make-lang.in: New file.
|
||||
* brig-builtins.h: Likewise.
|
||||
* brig-c.h: Likewise.
|
||||
* brig-lang.c: Likewise.
|
||||
* brigspec.c: Likewise.
|
||||
* config-lang.in: Likewise.
|
||||
* lang-specs.h: Likewise.
|
||||
* lang.opt: Likewise.
|
||||
* brigfrontend/brig-arg-block-handler.cc: Likewise.
|
||||
* brigfrontend/brig-atomic-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-basic-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-branch-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-cmp-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-code-entry-handler.cc: Likewise.
|
||||
* brigfrontend/brig-code-entry-handler.h: Likewise.
|
||||
* brigfrontend/brig-comment-handler.cc: Likewise.
|
||||
* brigfrontend/brig-control-handler.cc: Likewise.
|
||||
* brigfrontend/brig-copy-move-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-cvt-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-fbarrier-handler.cc: Likewise.
|
||||
* brigfrontend/brig-function-handler.cc: Likewise.
|
||||
* brigfrontend/brig-function.cc: Likewise.
|
||||
* brigfrontend/brig-function.h: Likewise.
|
||||
* brigfrontend/brig-inst-mod-handler.cc: Likewise.
|
||||
* brigfrontend/brig-label-handler.cc: Likewise.
|
||||
* brigfrontend/brig-lane-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-machine.c: Likewise.
|
||||
* brigfrontend/brig-machine.h: Likewise.
|
||||
* brigfrontend/brig-mem-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-module-handler.cc: Likewise.
|
||||
* brigfrontend/brig-queue-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-seg-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-signal-inst-handler.cc: Likewise.
|
||||
* brigfrontend/brig-to-generic.cc: Likewise.
|
||||
* brigfrontend/brig-to-generic.h: Likewise.
|
||||
* brigfrontend/brig-util.cc: Likewise.
|
||||
* brigfrontend/brig-util.h: Likewise.
|
||||
* brigfrontend/brig-variable-handler.cc: Likewise.
|
||||
* brigfrontend/phsa.h: Likewise.
|
247
gcc/brig/Make-lang.in
Normal file
247
gcc/brig/Make-lang.in
Normal file
|
@ -0,0 +1,247 @@
|
|||
# Make-lang.in -- Top level -*- makefile -*- fragment for gcc BRIG (HSAIL)
|
||||
# frontend.
|
||||
|
||||
# Copyright (C) 2015 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This file provides the language dependent support in the main Makefile.
|
||||
|
||||
# Installation name.
|
||||
|
||||
GCCBRIG_INSTALL_NAME := $(shell echo gccbrig|sed '$(program_transform_name)')
|
||||
GCCBRIG_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gccbrig|sed \
|
||||
'$(program_transform_name)')
|
||||
|
||||
# The name for selecting brig in LANGUAGES.
|
||||
brig: brig1$(exeext)
|
||||
|
||||
.PHONY: brig
|
||||
|
||||
CFLAGS-brig/brigspec.o += $(DRIVER_DEFINES)
|
||||
|
||||
GCCBRIG_OBJS = $(GCC_OBJS) brig/brigspec.o
|
||||
gccbrig$(exeext): $(GCCBRIG_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \
|
||||
$(LIBDEPS)
|
||||
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
|
||||
$(GCCBRIG_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \
|
||||
$(EXTRA_GCC_LIBS) $(LIBS)
|
||||
|
||||
# The cross-compiler version. This is built mainly as a signal to the
|
||||
# brig.install-common target. If this executable exists, it means that
|
||||
# brig.all.cross was run.
|
||||
gccbrig-cross$(exeext): gccbrig$(exeext)
|
||||
-rm -f gccbrig-cross$(exeext)
|
||||
cp gccbrig$(exeext) gccbrig-cross$(exeext)
|
||||
|
||||
# Use strict warnings.
|
||||
brig-warn = $(STRICT_WARN)
|
||||
|
||||
BRIG_OBJS = \
|
||||
brig/brig-lang.o \
|
||||
brig/brig-code-entry-handler.o \
|
||||
brig/brig-function-handler.o \
|
||||
brig/brig-variable-handler.o \
|
||||
brig/brig-fbarrier-handler.o \
|
||||
brig/brig-label-handler.o \
|
||||
brig/brig-comment-handler.o \
|
||||
brig/brig-basic-inst-handler.o \
|
||||
brig/brig-cvt-inst-handler.o \
|
||||
brig/brig-seg-inst-handler.o \
|
||||
brig/brig-lane-inst-handler.o \
|
||||
brig/brig-queue-inst-handler.o \
|
||||
brig/brig-copy-move-inst-handler.o \
|
||||
brig/brig-signal-inst-handler.o \
|
||||
brig/brig-atomic-inst-handler.o \
|
||||
brig/brig-arg-block-handler.o \
|
||||
brig/brig-control-handler.o \
|
||||
brig/brig-cmp-inst-handler.o \
|
||||
brig/brig-branch-inst-handler.o \
|
||||
brig/brig-mem-inst-handler.o \
|
||||
brig/brig-module-handler.o \
|
||||
brig/brig-inst-mod-handler.o \
|
||||
brig/brig-function.o \
|
||||
brig/brig-to-generic.o \
|
||||
brig/brig-machine.o \
|
||||
brig/brig-util.o
|
||||
|
||||
brig_OBJS = $(BRIG_OBJS) brig/brigspec.o
|
||||
|
||||
# brig1$(exeext): $(BRIG_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
|
||||
# +$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
|
||||
# $(BRIG_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
|
||||
|
||||
|
||||
brig1$(exeext): $(BRIG_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
|
||||
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
|
||||
$(BRIG_OBJS) attribs.o $(BACKEND) $(LIBS) \
|
||||
$(BACKENDLIBS)
|
||||
|
||||
# Documentation.
|
||||
|
||||
GO_TEXI_FILES = \
|
||||
brig/gccbrig.texi \
|
||||
$(gcc_docdir)/include/fdl.texi \
|
||||
$(gcc_docdir)/include/gpl_v3.texi \
|
||||
$(gcc_docdir)/include/gcc-common.texi \
|
||||
gcc-vers.texi
|
||||
|
||||
# doc/gccbrig.info: $(BRIG_TEXI_FILES)
|
||||
# if test "x$(BUILD_INFO)" = xinfo; then \
|
||||
# rm -f doc/gccbrig.info*; \
|
||||
# $(MAKEINFO) $(MAKEINFOFLAGS) -I $(gcc_docdir) \
|
||||
# -I $(gcc_docdir)/include -o $@ $<; \
|
||||
# else true; fi
|
||||
|
||||
# doc/gccbrig.dvi: $(BRIG_TEXI_FILES)
|
||||
# $(TEXI2DVI) -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $<
|
||||
|
||||
# doc/gccbrig.pdf: $(BRIG_TEXI_FILES)
|
||||
# $(TEXI2PDF) -I $(abs_docdir) -I $(abs_docdir)/include -o $@ $<
|
||||
|
||||
$(build_htmldir)/brig/index.html: $(BRIG_TEXI_FILES)
|
||||
$(mkinstalldirs) $(@D)
|
||||
rm -f $(@D)/*
|
||||
$(TEXI2HTML) -I $(gcc_docdir) -I $(gcc_docdir)/include \
|
||||
-I $(srcdir)/brig -o $(@D) $<
|
||||
|
||||
# Build hooks.
|
||||
|
||||
brig.all.cross: gccbrig-cross$(exeext)
|
||||
brig.start.encap: gccbrig$(exeext)
|
||||
brig.rest.encap:
|
||||
#brig.info: doc/gccbrig.info
|
||||
brig.info:
|
||||
brig.dvi: doc/gccbrig.dvi
|
||||
brig.pdf: doc/gccbrig.pdf
|
||||
brig.html: $(build_htmldir)/brig/index.html
|
||||
brig.srcinfo: #doc/gccbrig.info
|
||||
# -cp -p $^ $(srcdir)/doc
|
||||
|
||||
brig.srcextra:
|
||||
brig.tags: force
|
||||
cd $(srcdir)/brig; \
|
||||
etags -o TAGS.sub *.c *.h; \
|
||||
etags --include TAGS.sub --include ../TAGS.sub
|
||||
brig.man:
|
||||
|
||||
#brig.srcman: doc/gccbrig.1
|
||||
# -cp -p $^ $(srcdir)/doc
|
||||
|
||||
lang_checks += check-brig
|
||||
|
||||
# Install hooks.
|
||||
|
||||
brig.install-common: installdirs
|
||||
-rm -f $(DESTDIR)$(bindir)/$(GCCBRIG_INSTALL_NAME)$(exeext)
|
||||
$(INSTALL_PROGRAM) gccbrig$(exeext) \
|
||||
$(DESTDIR)$(bindir)/$(GCCBRIG_INSTALL_NAME)$(exeext)
|
||||
-if test -f brig1$(exeext); then \
|
||||
if test -f gccbrig-cross$(exeext); then \
|
||||
:; \
|
||||
else \
|
||||
rm -f $(DESTDIR)$(bindir)/$(GCCBRIG_TARGET_INSTALL_NAME)$(exeext); \
|
||||
( cd $(DESTDIR)$(bindir) && \
|
||||
$(LN) $(GCCBRIG_INSTALL_NAME)$(exeext) \
|
||||
$(GCCBRIG_TARGET_INSTALL_NAME)$(exeext) ); \
|
||||
fi; \
|
||||
fi
|
||||
|
||||
brig.install-plugin:
|
||||
|
||||
brig.install-info: #$(DESTDIR)$(infodir)/gccbrig.info
|
||||
|
||||
brig.install-pdf: doc/gccbrig.pdf
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(pdfdir)" || $(mkinstalldirs) "$(DESTDIR)$(pdfdir)/gcc"
|
||||
@for p in doc/gccbrig.pdf; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
f=$(pdf__strip_dir) \
|
||||
echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(pdfdir)/gcc/$$f'"; \
|
||||
$(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(pdfdir)/gcc/$$f"; \
|
||||
done
|
||||
|
||||
brig.install-html: $(build_htmldir)/brig
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(htmldir)" || $(mkinstalldirs) "$(DESTDIR)$(htmldir)"
|
||||
@for p in $(build_htmldir)/brig; do \
|
||||
if test -f "$$p" || test -d "$$p"; then d=""; else d="$(srcdir)/"; \
|
||||
fi; \
|
||||
f=$(html__strip_dir) \
|
||||
if test -d "$$d$$p"; then \
|
||||
echo " $(mkinstalldirs) '$(DESTDIR)$(htmldir)/$$f'"; \
|
||||
$(mkinstalldirs) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
|
||||
echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
|
||||
$(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f"; \
|
||||
else \
|
||||
echo " $(INSTALL_DATA) '$$d$$p' '$(DESTDIR)$(htmldir)/$$f'"; \
|
||||
$(INSTALL_DATA) "$$d$$p" "$(DESTDIR)$(htmldir)/$$f"; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
brig.install-man: #$(DESTDIR)$(man1dir)/$(GCCBRIG_INSTALL_NAME)$(man1ext)
|
||||
|
||||
#$(DESTDIR)$(man1dir)/$(GCCBRIG_INSTALL_NAME)$(man1ext): doc/gccbrig.1 \
|
||||
# installdirs
|
||||
# -rm -f $@
|
||||
# -$(INSTALL_DATA) $< $@
|
||||
# -chmod a-x $@
|
||||
|
||||
brig.uninstall:
|
||||
rm -rf $(DESTDIR)$(bindir)/$(GCCBRIG_INSTALL_NAME)$(exeext)
|
||||
rm -rf $(DESTDIR)$(man1dir)/$(GCCBRIG_INSTALL_NAME)$(man1ext)
|
||||
rm -rf $(DESTDIR)$(bindir)/$(GCCBRIG_TARGET_INSTALL_NAME)$(exeext)
|
||||
rm -rf $(DESTDIR)$(infodir)/gccbrig.info*
|
||||
|
||||
# Clean hooks.
|
||||
|
||||
brig.mostlyclean:
|
||||
-rm -f brig/*$(objext)
|
||||
-rm -f brig/*$(coverageexts)
|
||||
brig.clean:
|
||||
brig.distclean:
|
||||
brig.maintainer-clean:
|
||||
-rm -f $(docobjdir)/gccbrig.1
|
||||
|
||||
# Stage hooks.
|
||||
|
||||
brig.stage1: stage1-start
|
||||
-mv brig/*$(objext) stage1/brig
|
||||
brig.stage2: stage2-start
|
||||
-mv brig/*$(objext) stage2/brig
|
||||
brig.stage3: stage3-start
|
||||
-mv brig/*$(objext) stage3/brig
|
||||
brig.stage4: stage4-start
|
||||
-mv brig/*$(objext) stage4/brig
|
||||
brig.stageprofile: stageprofile-start
|
||||
-mv brig/*$(objext) stageprofile/brig
|
||||
brig.stagefeedback: stagefeedback-start
|
||||
-mv brig/*$(objext) stagefeedback/brig
|
||||
|
||||
CFLAGS-brig/brig-lang.o += -DDEFAULT_TARGET_VERSION=\"$(version)\" \
|
||||
-DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\"
|
||||
|
||||
BRIGINCLUDES = -I $(srcdir)/brig -I ${HOME}/local/include \
|
||||
-I $(srcdir)/brig/brigfrontend
|
||||
|
||||
brig/brig-machine.o: brig/brigfrontend/brig-machine.c
|
||||
$(COMPILE) $(BRIGINCLUDES) $<
|
||||
$(POSTCOMPILE)
|
||||
|
||||
brig/%.o: brig/brigfrontend/%.cc
|
||||
$(COMPILE) $(BRIGINCLUDES) $<
|
||||
$(POSTCOMPILE)
|
99
gcc/brig/brig-builtins.h
Normal file
99
gcc/brig/brig-builtins.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* brig-builtins.h -- brig builtin definitions
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
enum built_in_attribute
|
||||
{
|
||||
#define DEF_ATTR_NULL_TREE(ENUM) ENUM,
|
||||
#define DEF_ATTR_INT(ENUM, VALUE) ENUM,
|
||||
#define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
|
||||
#define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
|
||||
#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
|
||||
#include "builtin-attrs.def"
|
||||
#undef DEF_ATTR_NULL_TREE
|
||||
#undef DEF_ATTR_INT
|
||||
#undef DEF_ATTR_STRING
|
||||
#undef DEF_ATTR_IDENT
|
||||
#undef DEF_ATTR_TREE_LIST
|
||||
ATTR_LAST
|
||||
};
|
||||
|
||||
/* Builtin types. */
|
||||
|
||||
enum brig_builtin_type
|
||||
{
|
||||
#define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
|
||||
#define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
|
||||
#define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
|
||||
#define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
|
||||
#define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
|
||||
#define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
|
||||
#define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
|
||||
#define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6) NAME,
|
||||
#define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7) NAME,
|
||||
#define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7, ARG8) NAME,
|
||||
#define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7, ARG8, ARG9) NAME,
|
||||
#define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7, ARG8, ARG9, ARG10) NAME,
|
||||
#define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
|
||||
#define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
|
||||
#define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
|
||||
#define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
|
||||
#define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
|
||||
#define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
|
||||
#define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \
|
||||
NAME,
|
||||
#define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6) NAME,
|
||||
#define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7) NAME,
|
||||
#define DEF_POINTER_TYPE(NAME, TYPE) NAME,
|
||||
#include "builtin-types.def"
|
||||
#undef DEF_PRIMITIVE_TYPE
|
||||
#undef DEF_FUNCTION_TYPE_0
|
||||
#undef DEF_FUNCTION_TYPE_1
|
||||
#undef DEF_FUNCTION_TYPE_2
|
||||
#undef DEF_FUNCTION_TYPE_3
|
||||
#undef DEF_FUNCTION_TYPE_4
|
||||
#undef DEF_FUNCTION_TYPE_5
|
||||
#undef DEF_FUNCTION_TYPE_6
|
||||
#undef DEF_FUNCTION_TYPE_7
|
||||
#undef DEF_FUNCTION_TYPE_8
|
||||
#undef DEF_FUNCTION_TYPE_9
|
||||
#undef DEF_FUNCTION_TYPE_10
|
||||
#undef DEF_FUNCTION_TYPE_11
|
||||
#undef DEF_FUNCTION_TYPE_VAR_0
|
||||
#undef DEF_FUNCTION_TYPE_VAR_1
|
||||
#undef DEF_FUNCTION_TYPE_VAR_2
|
||||
#undef DEF_FUNCTION_TYPE_VAR_3
|
||||
#undef DEF_FUNCTION_TYPE_VAR_4
|
||||
#undef DEF_FUNCTION_TYPE_VAR_5
|
||||
#undef DEF_FUNCTION_TYPE_VAR_6
|
||||
#undef DEF_FUNCTION_TYPE_VAR_7
|
||||
#undef DEF_POINTER_TYPE
|
||||
BT_LAST
|
||||
};
|
||||
|
||||
typedef enum brig_builtin_type builtin_type;
|
66
gcc/brig/brig-c.h
Normal file
66
gcc/brig/brig-c.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* brig-c.h -- Header file for brig input's gcc C interface.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef BRIG_BRIG_C_H
|
||||
#define BRIG_BRIG_C_H
|
||||
|
||||
#define BRIG_EXTERN_C
|
||||
|
||||
#include "machmode.h"
|
||||
|
||||
/* Functions defined in the Brig frontend proper called by the GCC
|
||||
interface. */
|
||||
|
||||
extern int brig_enable_dump (const char *);
|
||||
extern int brig_enable_optimize (const char *);
|
||||
|
||||
extern void brig_add_search_path (const char *);
|
||||
|
||||
extern void brig_create_brigbrig (int int_type_size, int pointer_size,
|
||||
const char *pkgpath, const char *prefix,
|
||||
const char *relative_import_path);
|
||||
|
||||
extern void brig_parse_input_files (const char **, unsigned int,
|
||||
bool only_check_syntax,
|
||||
bool require_return_statement);
|
||||
extern void brig_write_globals (void);
|
||||
|
||||
extern tree brig_type_for_size (unsigned int bits, int unsignedp);
|
||||
extern tree brig_type_for_mode (enum machine_mode, int unsignedp);
|
||||
|
||||
/* Functions defined in the GCC interface called by the Brig frontend
|
||||
proper. */
|
||||
|
||||
extern void brig_preserve_from_gc (tree);
|
||||
|
||||
extern const char *brig_localize_identifier (const char *);
|
||||
|
||||
extern unsigned int brig_field_alignment (tree);
|
||||
|
||||
extern void brig_trampoline_info (unsigned int *size, unsigned int *alignment);
|
||||
|
||||
extern void brig_imported_unsafe (void);
|
||||
|
||||
extern void brig_write_export_data (const char *, unsigned int);
|
||||
|
||||
extern const char *brig_read_export_data (int, off_t, char **, size_t *, int *);
|
||||
|
||||
#endif /* !defined (BRIG_BRIG_C_H) */
|
807
gcc/brig/brig-lang.c
Normal file
807
gcc/brig/brig-lang.c
Normal file
|
@ -0,0 +1,807 @@
|
|||
/* brig-lang.c -- brig (HSAIL) input gcc interface.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "ansidecl.h"
|
||||
#include "coretypes.h"
|
||||
#include "opts.h"
|
||||
#include "tree.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "print-tree.h"
|
||||
#include "stringpool.h"
|
||||
#include "basic-block.h"
|
||||
#include "gimple-expr.h"
|
||||
#include "gimplify.h"
|
||||
#include "dumpfile.h"
|
||||
#include "stor-layout.h"
|
||||
#include "toplev.h"
|
||||
#include "debug.h"
|
||||
#include "options.h"
|
||||
#include "flags.h"
|
||||
#include "convert.h"
|
||||
#include "diagnostic.h"
|
||||
#include "langhooks.h"
|
||||
#include "langhooks-def.h"
|
||||
#include "target.h"
|
||||
#include "vec.h"
|
||||
#include "brigfrontend/brig-to-generic.h"
|
||||
#include "machmode.h"
|
||||
#include "fold-const.h"
|
||||
#include "common/common-target.h"
|
||||
#include <mpfr.h>
|
||||
#include "brig-c.h"
|
||||
#include "brig-builtins.h"
|
||||
|
||||
/* This file is based on Go frontent'd go-lang.c and gogo-tree.cc. */
|
||||
|
||||
/* If -v set. */
|
||||
|
||||
int gccbrig_verbose = 0;
|
||||
|
||||
/* Language-dependent contents of a type. */
|
||||
|
||||
struct GTY (()) lang_type
|
||||
{
|
||||
char dummy;
|
||||
};
|
||||
|
||||
/* Language-dependent contents of a decl. */
|
||||
|
||||
struct GTY ((variable_size)) lang_decl
|
||||
{
|
||||
char dummy;
|
||||
};
|
||||
|
||||
/* Language-dependent contents of an identifier. This must include a
|
||||
tree_identifier. */
|
||||
|
||||
struct GTY (()) lang_identifier
|
||||
{
|
||||
struct tree_identifier common;
|
||||
};
|
||||
|
||||
/* The resulting tree type. */
|
||||
|
||||
union GTY ((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
|
||||
chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), "
|
||||
"TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN "
|
||||
"(&%h.generic)) : NULL"))) lang_tree_node
|
||||
{
|
||||
union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic;
|
||||
struct lang_identifier GTY ((tag ("1"))) identifier;
|
||||
};
|
||||
|
||||
/* We don't use language_function. */
|
||||
|
||||
struct GTY (()) language_function
|
||||
{
|
||||
int dummy;
|
||||
};
|
||||
|
||||
|
||||
/* The option mask. */
|
||||
|
||||
static unsigned int
|
||||
brig_langhook_option_lang_mask (void)
|
||||
{
|
||||
return CL_BRIG;
|
||||
}
|
||||
|
||||
/* Initialize the options structure. */
|
||||
|
||||
static void
|
||||
brig_langhook_init_options_struct (struct gcc_options *opts)
|
||||
{
|
||||
/* Signed overflow is precisely defined. */
|
||||
opts->x_flag_wrapv = 1;
|
||||
|
||||
/* If we set this to one, the whole program optimizations internalize
|
||||
all global variables, making them invisible to the dyn loader (and
|
||||
thus the HSA runtime implementation). */
|
||||
opts->x_flag_whole_program = 0;
|
||||
|
||||
/* The builtin math functions should not set errno. */
|
||||
opts->x_flag_errno_math = 0;
|
||||
opts->frontend_set_flag_errno_math = false;
|
||||
|
||||
opts->x_flag_exceptions = 0;
|
||||
opts->x_flag_non_call_exceptions = 0;
|
||||
|
||||
opts->x_flag_finite_math_only = 0;
|
||||
opts->x_flag_signed_zeros = 1;
|
||||
}
|
||||
|
||||
/* Handle Brig specific options. Return 0 if we didn't do anything. */
|
||||
|
||||
static bool
|
||||
brig_langhook_handle_option
|
||||
(size_t scode, const char *arg ATTRIBUTE_UNUSED,
|
||||
int value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED,
|
||||
location_t loc ATTRIBUTE_UNUSED,
|
||||
const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
|
||||
{
|
||||
enum opt_code code = (enum opt_code) scode;
|
||||
switch (code)
|
||||
{
|
||||
case OPT_v:
|
||||
gccbrig_verbose = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Run after parsing options. */
|
||||
|
||||
static bool
|
||||
brig_langhook_post_options (const char **pfilename ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (flag_excess_precision_cmdline == EXCESS_PRECISION_DEFAULT)
|
||||
flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD;
|
||||
|
||||
/* gccbrig casts pointers around like crazy, TBAA produces
|
||||
broken code if not force disabling it. */
|
||||
flag_strict_aliasing = 0;
|
||||
|
||||
/* Returning false means that the backend should be used. */
|
||||
return false;
|
||||
}
|
||||
|
||||
static size_t
|
||||
get_file_size (FILE *file)
|
||||
{
|
||||
size_t size;
|
||||
fseek (file, 0, SEEK_END);
|
||||
size = (size_t) ftell (file);
|
||||
fseek (file, 0, SEEK_SET);
|
||||
return size;
|
||||
}
|
||||
|
||||
static void
|
||||
brig_langhook_parse_file (void)
|
||||
{
|
||||
brig_to_generic brig_to_gen;
|
||||
|
||||
for (unsigned int i = 0; i < num_in_fnames; ++i)
|
||||
{
|
||||
|
||||
FILE *f;
|
||||
f = fopen (in_fnames[i], "r");
|
||||
size_t fsize = get_file_size (f);
|
||||
char *brig_blob = new char[fsize];
|
||||
if (fread (brig_blob, 1, fsize, f) != fsize)
|
||||
{
|
||||
error ("could not read the BRIG file");
|
||||
exit (1);
|
||||
}
|
||||
brig_to_gen.parse (brig_blob);
|
||||
fclose (f);
|
||||
}
|
||||
|
||||
brig_to_gen.write_globals ();
|
||||
}
|
||||
|
||||
static tree
|
||||
brig_langhook_type_for_size (unsigned int bits,
|
||||
int unsignedp)
|
||||
{
|
||||
/* Copied from go-lang.c */
|
||||
tree type;
|
||||
if (unsignedp)
|
||||
{
|
||||
if (bits == INT_TYPE_SIZE)
|
||||
type = unsigned_type_node;
|
||||
else if (bits == CHAR_TYPE_SIZE)
|
||||
type = unsigned_char_type_node;
|
||||
else if (bits == SHORT_TYPE_SIZE)
|
||||
type = short_unsigned_type_node;
|
||||
else if (bits == LONG_TYPE_SIZE)
|
||||
type = long_unsigned_type_node;
|
||||
else if (bits == LONG_LONG_TYPE_SIZE)
|
||||
type = long_long_unsigned_type_node;
|
||||
else
|
||||
type = make_unsigned_type(bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bits == INT_TYPE_SIZE)
|
||||
type = integer_type_node;
|
||||
else if (bits == CHAR_TYPE_SIZE)
|
||||
type = signed_char_type_node;
|
||||
else if (bits == SHORT_TYPE_SIZE)
|
||||
type = short_integer_type_node;
|
||||
else if (bits == LONG_TYPE_SIZE)
|
||||
type = long_integer_type_node;
|
||||
else if (bits == LONG_LONG_TYPE_SIZE)
|
||||
type = long_long_integer_type_node;
|
||||
else
|
||||
type = make_signed_type(bits);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static tree
|
||||
brig_langhook_type_for_mode (enum machine_mode mode, int unsignedp)
|
||||
{
|
||||
if (mode == TYPE_MODE (void_type_node))
|
||||
return void_type_node;
|
||||
|
||||
if (VECTOR_MODE_P (mode))
|
||||
{
|
||||
tree inner;
|
||||
|
||||
inner = brig_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
|
||||
if (inner != NULL_TREE)
|
||||
return build_vector_type_for_mode (inner, mode);
|
||||
gcc_unreachable ();
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
enum mode_class mc = GET_MODE_CLASS (mode);
|
||||
if (mc == MODE_FLOAT)
|
||||
{
|
||||
switch (GET_MODE_BITSIZE (mode))
|
||||
{
|
||||
case 32:
|
||||
return float_type_node;
|
||||
case 64:
|
||||
return double_type_node;
|
||||
default:
|
||||
/* We have to check for long double in order to support
|
||||
i386 excess precision. */
|
||||
if (mode == TYPE_MODE (long_double_type_node))
|
||||
return long_double_type_node;
|
||||
|
||||
gcc_unreachable ();
|
||||
return NULL_TREE;
|
||||
}
|
||||
}
|
||||
else if (mc == MODE_INT)
|
||||
return brig_langhook_type_for_size(GET_MODE_BITSIZE(mode), unsignedp);
|
||||
else
|
||||
{
|
||||
/* E.g., build_common_builtin_nodes () asks for modes/builtins
|
||||
we do not generate or need. Just ignore them silently for now.
|
||||
*/
|
||||
return NULL_TREE;
|
||||
}
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
static tree
|
||||
brig_langhook_builtin_function (tree decl)
|
||||
{
|
||||
return decl;
|
||||
}
|
||||
|
||||
static GTY(()) tree registered_builtin_types;
|
||||
|
||||
static void
|
||||
brig_langhook_register_builtin_type (tree type, const char *name)
|
||||
{
|
||||
tree decl;
|
||||
|
||||
if (!TYPE_NAME (type))
|
||||
{
|
||||
decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
|
||||
get_identifier (name), type);
|
||||
DECL_ARTIFICIAL (decl) = 1;
|
||||
TYPE_NAME (type) = decl;
|
||||
}
|
||||
|
||||
registered_builtin_types = tree_cons (0, type, registered_builtin_types);
|
||||
}
|
||||
|
||||
|
||||
/* Return true if we are in the global binding level. */
|
||||
|
||||
static bool
|
||||
brig_langhook_global_bindings_p (void)
|
||||
{
|
||||
return current_function_decl == NULL_TREE;
|
||||
}
|
||||
|
||||
/* Push a declaration into the current binding level. From Go: We can't
|
||||
usefully implement this since we don't want to convert from tree
|
||||
back to one of our internal data structures. I think the only way
|
||||
this is used is to record a decl which is to be returned by
|
||||
getdecls, and we could implement it for that purpose if
|
||||
necessary. */
|
||||
|
||||
static tree
|
||||
brig_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
|
||||
{
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* This hook is used to get the current list of declarations as trees.
|
||||
From Go: We don't support that; instead we use the write_globals hook.
|
||||
This can't simply crash because it is called by -gstabs. */
|
||||
|
||||
static tree
|
||||
brig_langhook_getdecls (void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
brig_langhook_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
|
||||
gimple_seq *post_p ATTRIBUTE_UNUSED)
|
||||
{
|
||||
|
||||
/* Strip off the static chain info that appears to function
|
||||
calls for some strange reason even though we don't add
|
||||
nested functions. Maybe something wrong with the function
|
||||
declaration contexts? */
|
||||
if (TREE_CODE (*expr_p) == CALL_EXPR
|
||||
&& CALL_EXPR_STATIC_CHAIN (*expr_p) != NULL_TREE)
|
||||
CALL_EXPR_STATIC_CHAIN (*expr_p) = NULL_TREE;
|
||||
return GS_UNHANDLED;
|
||||
}
|
||||
|
||||
static tree
|
||||
brig_langhook_eh_personality (void)
|
||||
{
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* Functions called directly by the generic backend.
|
||||
Adapted from go-lang.c. */
|
||||
|
||||
tree
|
||||
convert (tree type, tree expr)
|
||||
{
|
||||
if (type == error_mark_node || expr == error_mark_node
|
||||
|| TREE_TYPE (expr) == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
if (type == TREE_TYPE (expr))
|
||||
return expr;
|
||||
|
||||
if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
|
||||
return fold_convert (type, expr);
|
||||
|
||||
switch (TREE_CODE (type))
|
||||
{
|
||||
case VOID_TYPE:
|
||||
case BOOLEAN_TYPE:
|
||||
return fold_convert (type, expr);
|
||||
case INTEGER_TYPE:
|
||||
return fold (convert_to_integer (type, expr));
|
||||
case REAL_TYPE:
|
||||
return fold (convert_to_real (type, expr));
|
||||
case VECTOR_TYPE:
|
||||
return fold (convert_to_vector (type, expr));
|
||||
case POINTER_TYPE:
|
||||
return build1 (VIEW_CONVERT_EXPR, type, convert (size_type_node, expr));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
static GTY (()) tree brig_gc_root;
|
||||
|
||||
/* Preserve trees that we create from the garbage collector. */
|
||||
|
||||
void
|
||||
brig_preserve_from_gc (tree t)
|
||||
{
|
||||
brig_gc_root = tree_cons (NULL_TREE, t, brig_gc_root);
|
||||
}
|
||||
|
||||
/* Convert an identifier for use in an error message. */
|
||||
|
||||
const char *
|
||||
brig_localize_identifier (const char *ident)
|
||||
{
|
||||
return identifier_to_locale (ident);
|
||||
}
|
||||
|
||||
/* Built-in initialization code cribbed from lto-lang.c which cribbed it
|
||||
from c-common.c. */
|
||||
|
||||
|
||||
static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
|
||||
|
||||
|
||||
static GTY(()) tree builtin_types[(int) BT_LAST + 1];
|
||||
|
||||
static GTY(()) tree string_type_node;
|
||||
static GTY(()) tree const_string_type_node;
|
||||
static GTY(()) tree wint_type_node;
|
||||
static GTY(()) tree intmax_type_node;
|
||||
static GTY(()) tree uintmax_type_node;
|
||||
static GTY(()) tree signed_size_type_node;
|
||||
|
||||
/* Flags needed to process builtins.def. */
|
||||
int flag_isoc94;
|
||||
int flag_isoc99;
|
||||
int flag_isoc11;
|
||||
|
||||
static void
|
||||
def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
|
||||
{
|
||||
tree t;
|
||||
tree *args = XALLOCAVEC (tree, n);
|
||||
va_list list;
|
||||
int i;
|
||||
bool err = false;
|
||||
|
||||
va_start (list, n);
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
builtin_type a = (builtin_type) va_arg (list, int);
|
||||
t = builtin_types[a];
|
||||
if (t == error_mark_node)
|
||||
err = true;
|
||||
args[i] = t;
|
||||
}
|
||||
va_end (list);
|
||||
|
||||
t = builtin_types[ret];
|
||||
if (err)
|
||||
t = error_mark_node;
|
||||
if (t == error_mark_node)
|
||||
;
|
||||
else if (var)
|
||||
t = build_varargs_function_type_array (t, n, args);
|
||||
else
|
||||
t = build_function_type_array (t, n, args);
|
||||
|
||||
builtin_types[def] = t;
|
||||
}
|
||||
|
||||
/* Used to help initialize the builtin-types.def table. When a type of
|
||||
the correct size doesn't exist, use error_mark_node instead of NULL.
|
||||
The later results in segfaults even when a decl using the type doesn't
|
||||
get invoked. */
|
||||
|
||||
static tree
|
||||
builtin_type_for_size (int size, bool unsignedp)
|
||||
{
|
||||
tree type = brig_langhook_type_for_size (size, unsignedp);
|
||||
return type ? type : error_mark_node;
|
||||
}
|
||||
|
||||
/* Support for DEF_BUILTIN. */
|
||||
|
||||
static void
|
||||
def_builtin_1 (enum built_in_function fncode, const char *name,
|
||||
enum built_in_class fnclass, tree fntype, tree libtype,
|
||||
bool both_p, bool fallback_p, bool nonansi_p,
|
||||
tree fnattrs, bool implicit_p)
|
||||
{
|
||||
tree decl;
|
||||
const char *libname;
|
||||
|
||||
if (fntype == error_mark_node)
|
||||
return;
|
||||
|
||||
libname = name + strlen ("__builtin_");
|
||||
decl = add_builtin_function (name, fntype, fncode, fnclass,
|
||||
(fallback_p ? libname : NULL),
|
||||
fnattrs);
|
||||
|
||||
if (both_p
|
||||
&& !flag_no_builtin
|
||||
&& !(nonansi_p && flag_no_nonansi_builtin))
|
||||
add_builtin_function (libname, libtype, fncode, fnclass,
|
||||
NULL, fnattrs);
|
||||
|
||||
set_builtin_decl (fncode, decl, implicit_p);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the attribute table for all the supported builtins. */
|
||||
|
||||
static void
|
||||
brig_init_attributes (void)
|
||||
{
|
||||
/* Fill in the built_in_attributes array. */
|
||||
#define DEF_ATTR_NULL_TREE(ENUM) \
|
||||
built_in_attributes[(int) ENUM] = NULL_TREE;
|
||||
#define DEF_ATTR_INT(ENUM, VALUE) \
|
||||
built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
|
||||
#define DEF_ATTR_STRING(ENUM, VALUE) \
|
||||
built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
|
||||
#define DEF_ATTR_IDENT(ENUM, STRING) \
|
||||
built_in_attributes[(int) ENUM] = get_identifier (STRING);
|
||||
#define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
|
||||
built_in_attributes[(int) ENUM] \
|
||||
= tree_cons (built_in_attributes[(int) PURPOSE], \
|
||||
built_in_attributes[(int) VALUE], \
|
||||
built_in_attributes[(int) CHAIN]);
|
||||
#include "builtin-attrs.def"
|
||||
#undef DEF_ATTR_NULL_TREE
|
||||
#undef DEF_ATTR_INT
|
||||
#undef DEF_ATTR_STRING
|
||||
#undef DEF_ATTR_IDENT
|
||||
#undef DEF_ATTR_TREE_LIST
|
||||
}
|
||||
|
||||
/* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and
|
||||
VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */
|
||||
|
||||
static void
|
||||
brig_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
|
||||
tree va_list_arg_type_node ATTRIBUTE_UNUSED)
|
||||
{
|
||||
#define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
|
||||
builtin_types[ENUM] = VALUE;
|
||||
#define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
|
||||
def_fn_type (ENUM, RETURN, 0, 0);
|
||||
#define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
|
||||
def_fn_type (ENUM, RETURN, 0, 1, ARG1);
|
||||
#define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
|
||||
def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
|
||||
#define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
|
||||
def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
|
||||
#define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
|
||||
def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
|
||||
#define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
|
||||
def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
|
||||
#define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6) \
|
||||
def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
|
||||
#define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7) \
|
||||
def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
|
||||
#define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7, ARG8) \
|
||||
def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
|
||||
ARG7, ARG8);
|
||||
#define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7, ARG8, ARG9) \
|
||||
def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
|
||||
ARG7, ARG8, ARG9);
|
||||
#define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7, ARG8, ARG9, ARG10) \
|
||||
def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
|
||||
ARG7, ARG8, ARG9, ARG10);
|
||||
#define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
|
||||
def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
|
||||
ARG7, ARG8, ARG9, ARG10, ARG11);
|
||||
#define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
|
||||
def_fn_type (ENUM, RETURN, 1, 0);
|
||||
#define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
|
||||
def_fn_type (ENUM, RETURN, 1, 1, ARG1);
|
||||
#define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
|
||||
def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
|
||||
#define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
|
||||
def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
|
||||
#define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
|
||||
def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
|
||||
#define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
|
||||
def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
|
||||
#define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6) \
|
||||
def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
|
||||
#define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
|
||||
ARG6, ARG7) \
|
||||
def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
|
||||
#define DEF_POINTER_TYPE(ENUM, TYPE) \
|
||||
builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
|
||||
|
||||
#include "builtin-types.def"
|
||||
|
||||
#undef DEF_PRIMITIVE_TYPE
|
||||
#undef DEF_FUNCTION_TYPE_0
|
||||
#undef DEF_FUNCTION_TYPE_1
|
||||
#undef DEF_FUNCTION_TYPE_2
|
||||
#undef DEF_FUNCTION_TYPE_3
|
||||
#undef DEF_FUNCTION_TYPE_4
|
||||
#undef DEF_FUNCTION_TYPE_5
|
||||
#undef DEF_FUNCTION_TYPE_6
|
||||
#undef DEF_FUNCTION_TYPE_7
|
||||
#undef DEF_FUNCTION_TYPE_8
|
||||
#undef DEF_FUNCTION_TYPE_9
|
||||
#undef DEF_FUNCTION_TYPE_10
|
||||
#undef DEF_FUNCTION_TYPE_11
|
||||
#undef DEF_FUNCTION_TYPE_VAR_0
|
||||
#undef DEF_FUNCTION_TYPE_VAR_1
|
||||
#undef DEF_FUNCTION_TYPE_VAR_2
|
||||
#undef DEF_FUNCTION_TYPE_VAR_3
|
||||
#undef DEF_FUNCTION_TYPE_VAR_4
|
||||
#undef DEF_FUNCTION_TYPE_VAR_5
|
||||
#undef DEF_FUNCTION_TYPE_VAR_6
|
||||
#undef DEF_FUNCTION_TYPE_VAR_7
|
||||
#undef DEF_POINTER_TYPE
|
||||
builtin_types[(int) BT_LAST] = NULL_TREE;
|
||||
|
||||
brig_init_attributes ();
|
||||
|
||||
#define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P,\
|
||||
NONANSI_P, ATTRS, IMPLICIT, COND) \
|
||||
if (NAME && COND) \
|
||||
def_builtin_1 (ENUM, NAME, CLASS, builtin_types[(int) TYPE], \
|
||||
builtin_types[(int) LIBTYPE], BOTH_P, FALLBACK_P, \
|
||||
NONANSI_P, built_in_attributes[(int) ATTRS], IMPLICIT);
|
||||
|
||||
#undef DEF_HSAIL_BUILTIN
|
||||
#define DEF_HSAIL_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
false, true, true, ATTRS, false, true)
|
||||
|
||||
/* HSAIL atomic builtins do not have separate identifying opcodes. */
|
||||
|
||||
#undef DEF_HSAIL_ATOMIC_BUILTIN
|
||||
#define DEF_HSAIL_ATOMIC_BUILTIN(ENUM, ATOMIC_OPCODE, HSAIL_TYPE, NAME, \
|
||||
TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
false, true, true, ATTRS, false, true)
|
||||
|
||||
/* HSAIL saturating arithmetics builtins. */
|
||||
|
||||
#undef DEF_HSAIL_SAT_BUILTIN
|
||||
#define DEF_HSAIL_SAT_BUILTIN(ENUM, BRIG_OPCODE, HSAIL_TYPE, NAME, \
|
||||
TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
false, true, true, ATTRS, false, true)
|
||||
|
||||
/* HSAIL builtins used internally by the frontend. */
|
||||
|
||||
#undef DEF_HSAIL_INTR_BUILTIN
|
||||
#define DEF_HSAIL_INTR_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
false, true, true, ATTRS, false, true)
|
||||
|
||||
/* HSAIL saturated conversions. */
|
||||
|
||||
#undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN
|
||||
#define DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN(ENUM, HSAIL_DEST_TYPE, HSAIL_SRC_TYPE, \
|
||||
NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
|
||||
false, true, true, ATTRS, false, true)
|
||||
|
||||
#include "builtins.def"
|
||||
}
|
||||
|
||||
/* Build nodes that would have be created by the C front-end; necessary
|
||||
for including builtin-types.def and ultimately builtins.def. Borrowed
|
||||
from lto-lang.c. */
|
||||
|
||||
static void
|
||||
brig_build_c_type_nodes (void)
|
||||
{
|
||||
gcc_assert (void_type_node);
|
||||
|
||||
void_list_node = build_tree_list (NULL_TREE, void_type_node);
|
||||
string_type_node = build_pointer_type (char_type_node);
|
||||
const_string_type_node
|
||||
= build_pointer_type (build_qualified_type (char_type_node,
|
||||
TYPE_QUAL_CONST));
|
||||
|
||||
if (strcmp (SIZE_TYPE, "unsigned int") == 0)
|
||||
{
|
||||
intmax_type_node = integer_type_node;
|
||||
uintmax_type_node = unsigned_type_node;
|
||||
signed_size_type_node = integer_type_node;
|
||||
}
|
||||
else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
|
||||
{
|
||||
intmax_type_node = long_integer_type_node;
|
||||
uintmax_type_node = long_unsigned_type_node;
|
||||
signed_size_type_node = long_integer_type_node;
|
||||
}
|
||||
else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
|
||||
{
|
||||
intmax_type_node = long_long_integer_type_node;
|
||||
uintmax_type_node = long_long_unsigned_type_node;
|
||||
signed_size_type_node = long_long_integer_type_node;
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
signed_size_type_node = NULL_TREE;
|
||||
for (i = 0; i < NUM_INT_N_ENTS; i++)
|
||||
if (int_n_enabled_p[i])
|
||||
{
|
||||
char name[50];
|
||||
sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
|
||||
|
||||
if (strcmp (name, SIZE_TYPE) == 0)
|
||||
{
|
||||
intmax_type_node = int_n_trees[i].signed_type;
|
||||
uintmax_type_node = int_n_trees[i].unsigned_type;
|
||||
signed_size_type_node = int_n_trees[i].signed_type;
|
||||
}
|
||||
}
|
||||
if (signed_size_type_node == NULL_TREE)
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
wint_type_node = unsigned_type_node;
|
||||
pid_type_node = integer_type_node;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
brig_langhook_init (void)
|
||||
{
|
||||
build_common_tree_nodes (false);
|
||||
|
||||
/* Builtin initialization related code borrowed from lto-lang.c. */
|
||||
void_list_node = build_tree_list (NULL_TREE, void_type_node);
|
||||
|
||||
brig_build_c_type_nodes ();
|
||||
|
||||
if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
|
||||
{
|
||||
tree x = build_pointer_type (TREE_TYPE (va_list_type_node));
|
||||
brig_define_builtins (x, x);
|
||||
}
|
||||
else
|
||||
{
|
||||
brig_define_builtins (build_reference_type (va_list_type_node),
|
||||
va_list_type_node);
|
||||
}
|
||||
|
||||
targetm.init_builtins ();
|
||||
build_common_builtin_nodes ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef LANG_HOOKS_NAME
|
||||
#undef LANG_HOOKS_INIT
|
||||
#undef LANG_HOOKS_OPTION_LANG_MASK
|
||||
#undef LANG_HOOKS_INIT_OPTIONS_STRUCT
|
||||
#undef LANG_HOOKS_HANDLE_OPTION
|
||||
#undef LANG_HOOKS_POST_OPTIONS
|
||||
#undef LANG_HOOKS_PARSE_FILE
|
||||
#undef LANG_HOOKS_TYPE_FOR_MODE
|
||||
#undef LANG_HOOKS_TYPE_FOR_SIZE
|
||||
#undef LANG_HOOKS_REGISTER_BUILTIN_TYPE
|
||||
#undef LANG_HOOKS_BUILTIN_FUNCTION
|
||||
#undef LANG_HOOKS_GLOBAL_BINDINGS_P
|
||||
#undef LANG_HOOKS_PUSHDECL
|
||||
#undef LANG_HOOKS_GETDECLS
|
||||
#undef LANG_HOOKS_WRITE_GLOBALS
|
||||
#undef LANG_HOOKS_GIMPLIFY_EXPR
|
||||
#undef LANG_HOOKS_EH_PERSONALITY
|
||||
|
||||
#define LANG_HOOKS_NAME "GNU Brig"
|
||||
#define LANG_HOOKS_INIT brig_langhook_init
|
||||
#define LANG_HOOKS_OPTION_LANG_MASK brig_langhook_option_lang_mask
|
||||
#define LANG_HOOKS_INIT_OPTIONS_STRUCT brig_langhook_init_options_struct
|
||||
#define LANG_HOOKS_HANDLE_OPTION brig_langhook_handle_option
|
||||
#define LANG_HOOKS_POST_OPTIONS brig_langhook_post_options
|
||||
#define LANG_HOOKS_PARSE_FILE brig_langhook_parse_file
|
||||
#define LANG_HOOKS_TYPE_FOR_MODE brig_langhook_type_for_mode
|
||||
#define LANG_HOOKS_TYPE_FOR_SIZE brig_langhook_type_for_size
|
||||
#define LANG_HOOKS_REGISTER_BUILTIN_TYPE brig_langhook_register_builtin_type
|
||||
#define LANG_HOOKS_BUILTIN_FUNCTION brig_langhook_builtin_function
|
||||
#define LANG_HOOKS_GLOBAL_BINDINGS_P brig_langhook_global_bindings_p
|
||||
#define LANG_HOOKS_PUSHDECL brig_langhook_pushdecl
|
||||
#define LANG_HOOKS_GETDECLS brig_langhook_getdecls
|
||||
#define LANG_HOOKS_GIMPLIFY_EXPR brig_langhook_gimplify_expr
|
||||
#define LANG_HOOKS_EH_PERSONALITY brig_langhook_eh_personality
|
||||
|
||||
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
|
||||
|
||||
#include "gt-brig-brig-lang.h"
|
||||
#include "gtype-brig.h"
|
66
gcc/brig/brigfrontend/brig-arg-block-handler.cc
Normal file
66
gcc/brig/brigfrontend/brig-arg-block-handler.cc
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* brig-arg-block-handler.cc -- brig arg block start/end directive handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "system.h"
|
||||
#include "errors.h"
|
||||
|
||||
#include "tree-pretty-print.h"
|
||||
#include "print-tree.h"
|
||||
|
||||
size_t
|
||||
brig_directive_arg_block_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
if (base->kind == BRIG_KIND_DIRECTIVE_ARG_BLOCK_START)
|
||||
{
|
||||
/* Initiate a new code block for the call site. */
|
||||
tree stmt_list = alloc_stmt_list ();
|
||||
tree bind_expr
|
||||
= build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL);
|
||||
tree block = make_node (BLOCK);
|
||||
BIND_EXPR_BLOCK (bind_expr) = block;
|
||||
static int block_id = 0;
|
||||
BLOCK_NUMBER (block) = block_id++;
|
||||
TREE_USED (block) = 1;
|
||||
tree m_parentblock = DECL_INITIAL (m_parent.m_cf->m_func_decl);
|
||||
BLOCK_SUPERCONTEXT (block) = m_parentblock;
|
||||
|
||||
chainon (BLOCK_SUBBLOCKS (m_parentblock), block);
|
||||
|
||||
m_parent.m_cf->m_current_bind_expr = bind_expr;
|
||||
m_parent.m_cf->m_generating_arg_block = true;
|
||||
}
|
||||
else if (base->kind == BRIG_KIND_DIRECTIVE_ARG_BLOCK_END)
|
||||
{
|
||||
/* Restore the used bind expression back to the function
|
||||
scope. */
|
||||
tree new_bind_expr = m_parent.m_cf->m_current_bind_expr;
|
||||
m_parent.m_cf->m_current_bind_expr
|
||||
= DECL_SAVED_TREE (m_parent.m_cf->m_func_decl);
|
||||
m_parent.m_cf->append_statement (new_bind_expr);
|
||||
m_parent.m_cf->m_generating_arg_block = false;
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
return base->byteCount;
|
||||
}
|
265
gcc/brig/brigfrontend/brig-atomic-inst-handler.cc
Normal file
265
gcc/brig/brigfrontend/brig-atomic-inst-handler.cc
Normal file
|
@ -0,0 +1,265 @@
|
|||
/* brig-atomic-inst-handler.cc -- brig atomic instruction handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "brig-util.h"
|
||||
#include "fold-const.h"
|
||||
#include "diagnostic.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "print-tree.h"
|
||||
#include "convert.h"
|
||||
#include "langhooks.h"
|
||||
#include "gimple-expr.h"
|
||||
#include "stringpool.h"
|
||||
#include "brig-builtins.h"
|
||||
|
||||
brig_atomic_inst_handler::brig_atomic_inst_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_atomic_inst_handler::generate_tree (const BrigInstBase &inst,
|
||||
BrigAtomicOperation8_t atomic_opcode)
|
||||
{
|
||||
tree_stl_vec operands = build_operands (inst);
|
||||
const int first_input
|
||||
= gccbrig_hsa_opcode_op_output_p (inst.opcode, 0) ? 1 : 0;
|
||||
|
||||
tree instr_type = gccbrig_tree_type_for_hsa_type (inst.type);
|
||||
|
||||
/* Utilize the atomic data types (from C++11 support) for implementing
|
||||
atomic operations. */
|
||||
|
||||
tree atomic_type = build_qualified_type (instr_type, TYPE_QUAL_ATOMIC);
|
||||
|
||||
gcc_assert (atomic_type != NULL_TREE);
|
||||
|
||||
tree signal_handle = operands[first_input];
|
||||
tree atomic_ptype = build_pointer_type (atomic_type);
|
||||
tree casted_to_ptr = convert_to_pointer (atomic_ptype, signal_handle);
|
||||
|
||||
tree src0 = NULL_TREE;
|
||||
if (atomic_opcode != BRIG_ATOMIC_LD)
|
||||
src0 = operands[first_input + 1];
|
||||
|
||||
tree instr_expr = NULL_TREE;
|
||||
|
||||
tree ptype = build_pointer_type (instr_type);
|
||||
tree ptr = convert_to_pointer (ptype, operands[first_input]);
|
||||
|
||||
if (atomic_opcode == BRIG_ATOMIC_ST)
|
||||
{
|
||||
tree mem_ref = build2 (MEM_REF, atomic_type, casted_to_ptr,
|
||||
build_int_cst (atomic_ptype, 0));
|
||||
instr_expr = build2 (MODIFY_EXPR, atomic_type, mem_ref, src0);
|
||||
}
|
||||
else if (atomic_opcode == BRIG_ATOMIC_LD
|
||||
|| (atomic_opcode >= BRIG_ATOMIC_WAIT_EQ
|
||||
&& atomic_opcode <= BRIG_ATOMIC_WAITTIMEOUT_GTE))
|
||||
{
|
||||
tree mem_ref = build2 (MEM_REF, atomic_type, casted_to_ptr,
|
||||
build_int_cst (atomic_ptype, 0));
|
||||
/* signal_wait* instructions can return spuriously before the
|
||||
condition becomes true. Therefore it's legal to return
|
||||
right away. TODO: builtin calls which can be
|
||||
implemented with a power efficient sleep-wait. */
|
||||
instr_expr = mem_ref;
|
||||
}
|
||||
else if (atomic_opcode == BRIG_ATOMIC_CAS)
|
||||
{
|
||||
/* Special case for CAS due to the two args. */
|
||||
tree built_in = NULL_TREE;
|
||||
switch (gccbrig_hsa_type_bit_size (inst.type))
|
||||
{
|
||||
case 32:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4);
|
||||
break;
|
||||
case 64:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
tree src1 = operands[first_input + 2];
|
||||
|
||||
tree src0_type
|
||||
= TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (built_in))));
|
||||
|
||||
tree src1_type = TREE_VALUE
|
||||
(TREE_CHAIN (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (built_in)))));
|
||||
|
||||
instr_expr = call_builtin (built_in, 3, instr_type, ptype, ptr,
|
||||
src0_type, src0, src1_type, src1);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree built_in = NULL_TREE;
|
||||
/* The rest of the builtins have the same number of parameters.
|
||||
Generate a big if..else that finds the correct builtin
|
||||
automagically from the def file. */
|
||||
#undef DEF_HSAIL_SAT_BUILTIN
|
||||
#undef DEF_HSAIL_BUILTIN
|
||||
#undef DEF_HSAIL_ATOMIC_BUILTIN
|
||||
#undef DEF_HSAIL_INTR_BUILTIN
|
||||
#undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN
|
||||
|
||||
#define DEF_HSAIL_ATOMIC_BUILTIN(ENUM, ATOMIC_OPCODE, HSAIL_TYPE, \
|
||||
NAME, TYPE, ATTRS) \
|
||||
if (atomic_opcode == ATOMIC_OPCODE && inst.type == HSAIL_TYPE) \
|
||||
built_in = builtin_decl_explicit (ENUM); \
|
||||
else
|
||||
#include "brig-builtins.def"
|
||||
switch (atomic_opcode)
|
||||
{
|
||||
case BRIG_ATOMIC_ADD:
|
||||
switch (gccbrig_hsa_type_bit_size (inst.type))
|
||||
{
|
||||
case 32:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_ADD_4);
|
||||
break;
|
||||
case 64:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_ADD_8);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
break;
|
||||
case BRIG_ATOMIC_SUB:
|
||||
switch (gccbrig_hsa_type_bit_size (inst.type))
|
||||
{
|
||||
case 32:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_SUB_4);
|
||||
break;
|
||||
case 64:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_SUB_8);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
break;
|
||||
case BRIG_ATOMIC_AND:
|
||||
switch (gccbrig_hsa_type_bit_size (inst.type))
|
||||
{
|
||||
case 32:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_AND_4);
|
||||
break;
|
||||
case 64:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_AND_8);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
break;
|
||||
case BRIG_ATOMIC_XOR:
|
||||
switch (gccbrig_hsa_type_bit_size (inst.type))
|
||||
{
|
||||
case 32:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_XOR_4);
|
||||
break;
|
||||
case 64:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_XOR_8);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
break;
|
||||
case BRIG_ATOMIC_OR:
|
||||
switch (gccbrig_hsa_type_bit_size (inst.type))
|
||||
{
|
||||
case 32:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_OR_4);
|
||||
break;
|
||||
case 64:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_FETCH_AND_OR_8);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
break;
|
||||
case BRIG_ATOMIC_EXCH:
|
||||
switch (gccbrig_hsa_type_bit_size (inst.type))
|
||||
{
|
||||
case 32:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_LOCK_TEST_AND_SET_4);
|
||||
break;
|
||||
case 64:
|
||||
built_in
|
||||
= builtin_decl_explicit (BUILT_IN_SYNC_LOCK_TEST_AND_SET_8);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
};
|
||||
|
||||
gcc_assert (built_in != NULL_TREE);
|
||||
tree arg0_type
|
||||
= TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (built_in))));
|
||||
|
||||
instr_expr = call_builtin (built_in, 2, instr_type, ptr_type_node,
|
||||
ptr, arg0_type, src0);
|
||||
|
||||
/* We need a temp variable for the result, because otherwise
|
||||
the gimplifier drops a necessary (unsigned to signed) cast in
|
||||
the output assignment and fails a check later. */
|
||||
tree tmp_var = create_tmp_var (arg0_type, "builtin_out");
|
||||
tree tmp_assign
|
||||
= build2 (MODIFY_EXPR, TREE_TYPE (tmp_var), tmp_var, instr_expr);
|
||||
m_parent.m_cf->append_statement (tmp_assign);
|
||||
instr_expr = tmp_var;
|
||||
}
|
||||
|
||||
if (first_input > 0)
|
||||
build_output_assignment (inst, operands[0], instr_expr);
|
||||
else
|
||||
m_parent.m_cf->append_statement (instr_expr);
|
||||
|
||||
return inst.base.byteCount;
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_atomic_inst_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigInstAtomic *inst = (const BrigInstAtomic *) base;
|
||||
BrigAtomicOperation8_t atomic_opcode;
|
||||
atomic_opcode = inst->atomicOperation;
|
||||
|
||||
return generate_tree (inst->base, atomic_opcode);
|
||||
}
|
865
gcc/brig/brigfrontend/brig-basic-inst-handler.cc
Normal file
865
gcc/brig/brigfrontend/brig-basic-inst-handler.cc
Normal file
|
@ -0,0 +1,865 @@
|
|||
/* brig-basic-inst-handler.cc -- brig basic instruction handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "brig-util.h"
|
||||
|
||||
#include "errors.h"
|
||||
#include "gimple-expr.h"
|
||||
#include "convert.h"
|
||||
#include "print-tree.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "langhooks.h"
|
||||
#include "stor-layout.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "brig-builtins.h"
|
||||
|
||||
brig_basic_inst_handler::brig_basic_inst_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
class scalarized_sat_arithmetics : public tree_element_binary_visitor
|
||||
{
|
||||
public:
|
||||
scalarized_sat_arithmetics (const BrigInstBase &brig_inst)
|
||||
: m_brig_inst (brig_inst)
|
||||
{
|
||||
BrigType16_t element_type = brig_inst.type & BRIG_TYPE_BASE_MASK;
|
||||
|
||||
#undef DEF_HSAIL_SAT_BUILTIN
|
||||
#undef DEF_HSAIL_BUILTIN
|
||||
#undef DEF_HSAIL_ATOMIC_BUILTIN
|
||||
#undef DEF_HSAIL_INTR_BUILTIN
|
||||
#undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN
|
||||
|
||||
#define DEF_HSAIL_SAT_BUILTIN(ENUM, BRIG_OPCODE, HSAIL_TYPE, \
|
||||
NAME, TYPE, ATTRS) \
|
||||
if (brig_inst.opcode == BRIG_OPCODE && element_type == HSAIL_TYPE) \
|
||||
m_builtin = builtin_decl_explicit (ENUM); \
|
||||
else
|
||||
#include "brig-builtins.def"
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
virtual tree
|
||||
visit_element (brig_code_entry_handler &, tree operand0, tree operand1)
|
||||
{
|
||||
/* Implement saturating arithmetics with scalar built-ins for now.
|
||||
TODO: emit GENERIC nodes for the simplest cases or at least
|
||||
emit vector built-ins. */
|
||||
return call_builtin (m_builtin, 2, TREE_TYPE (operand0),
|
||||
TREE_TYPE (operand0), operand0,
|
||||
TREE_TYPE (operand1), operand1);
|
||||
}
|
||||
const BrigInstBase &m_brig_inst;
|
||||
tree m_builtin;
|
||||
};
|
||||
|
||||
/* Implements a vector shuffle. ARITH_TYPE is the type of the vector,
|
||||
OPERANDS[0] is the first vector, OPERAND[1] the second vector and
|
||||
OPERANDS[2] the shuffle mask in HSAIL format. The output is a VEC_PERM_EXPR
|
||||
that implements the shuffle as a GENERIC expression. */
|
||||
|
||||
tree
|
||||
brig_basic_inst_handler::build_shuffle (tree arith_type,
|
||||
tree_stl_vec &operands)
|
||||
{
|
||||
tree element_type
|
||||
= get_unsigned_int_type (TREE_TYPE (TREE_TYPE (operands[0])));
|
||||
|
||||
/* Offsets to add to the mask values to convert from the
|
||||
HSAIL mask to VEC_PERM_EXPR masks. VEC_PERM_EXPR mask
|
||||
assumes an index spanning from 0 to 2 times the vec
|
||||
width while HSAIL refers separately to two different
|
||||
input vectors, thus is not a "full shuffle" where all
|
||||
output elements can originate from any input element. */
|
||||
vec<constructor_elt, va_gc> *mask_offset_vals = NULL;
|
||||
|
||||
vec<constructor_elt, va_gc> *input_mask_vals = NULL;
|
||||
size_t input_mask_element_size
|
||||
= exact_log2 (TYPE_VECTOR_SUBPARTS (arith_type));
|
||||
|
||||
/* Unpack the tightly packed mask elements to BIT_FIELD_REFs
|
||||
from which to construct the mask vector as understood by
|
||||
VEC_PERM_EXPR. */
|
||||
tree mask_operand = add_temp_var ("shuffle_mask", operands[2]);
|
||||
|
||||
tree mask_element_type
|
||||
= build_nonstandard_integer_type (input_mask_element_size, true);
|
||||
|
||||
for (size_t i = 0; i < TYPE_VECTOR_SUBPARTS (arith_type); ++i)
|
||||
{
|
||||
tree mask_element
|
||||
= build3 (BIT_FIELD_REF, mask_element_type, mask_operand,
|
||||
build_int_cst (unsigned_char_type_node,
|
||||
input_mask_element_size),
|
||||
build_int_cst (unsigned_char_type_node,
|
||||
i * input_mask_element_size));
|
||||
|
||||
mask_element = convert (element_type, mask_element);
|
||||
|
||||
tree offset;
|
||||
if (i < TYPE_VECTOR_SUBPARTS (arith_type) / 2)
|
||||
offset = build_int_cst (element_type, 0);
|
||||
else
|
||||
offset
|
||||
= build_int_cst (element_type, TYPE_VECTOR_SUBPARTS (arith_type));
|
||||
|
||||
CONSTRUCTOR_APPEND_ELT (mask_offset_vals, NULL_TREE, offset);
|
||||
CONSTRUCTOR_APPEND_ELT (input_mask_vals, NULL_TREE, mask_element);
|
||||
}
|
||||
tree mask_vec_type
|
||||
= build_vector_type (element_type, TYPE_VECTOR_SUBPARTS (arith_type));
|
||||
|
||||
tree mask_vec = build_constructor (mask_vec_type, input_mask_vals);
|
||||
tree offset_vec = build_constructor (mask_vec_type, mask_offset_vals);
|
||||
|
||||
tree mask = build2 (PLUS_EXPR, mask_vec_type, mask_vec, offset_vec);
|
||||
|
||||
tree perm = build3 (VEC_PERM_EXPR, TREE_TYPE (operands[0]), operands[0],
|
||||
operands[1], mask);
|
||||
return perm;
|
||||
}
|
||||
|
||||
/* Unpacks (extracts) a scalar element with an index in OPERANDS[1]
|
||||
from the vector expression in OPERANDS[0]. */
|
||||
|
||||
tree
|
||||
brig_basic_inst_handler::build_unpack (tree_stl_vec &operands)
|
||||
{
|
||||
/* Implement the unpack with a shuffle that stores the unpacked
|
||||
element to the lowest bit positions in the dest. After that
|
||||
a bitwise AND is used to clear the uppermost bits. */
|
||||
tree src_element_type = TREE_TYPE (TREE_TYPE (operands[0]));
|
||||
|
||||
/* Perform the operations with a raw (unsigned int type) type. */
|
||||
tree element_type = get_unsigned_int_type (src_element_type);
|
||||
|
||||
vec<constructor_elt, va_gc> *input_mask_vals = NULL;
|
||||
vec<constructor_elt, va_gc> *and_mask_vals = NULL;
|
||||
|
||||
size_t element_count = TYPE_VECTOR_SUBPARTS (TREE_TYPE (operands[0]));
|
||||
tree vec_type = build_vector_type (element_type, element_count);
|
||||
|
||||
for (size_t i = 0; i < element_count; ++i)
|
||||
{
|
||||
tree mask_element;
|
||||
if (i == 0)
|
||||
mask_element = convert (element_type, operands[1]);
|
||||
else
|
||||
mask_element = build_int_cst (element_type, 0);
|
||||
|
||||
CONSTRUCTOR_APPEND_ELT (input_mask_vals, NULL_TREE, mask_element);
|
||||
|
||||
tree and_mask_element;
|
||||
if (i == 0)
|
||||
and_mask_element = build_int_cst (element_type, -1);
|
||||
else
|
||||
and_mask_element = build_int_cst (element_type, 0);
|
||||
CONSTRUCTOR_APPEND_ELT (and_mask_vals, NULL_TREE, and_mask_element);
|
||||
}
|
||||
|
||||
tree mask_vec = build_constructor (vec_type, input_mask_vals);
|
||||
|
||||
tree and_mask_vec = build_constructor (vec_type, and_mask_vals);
|
||||
|
||||
tree perm = build3 (VEC_PERM_EXPR, vec_type,
|
||||
build_reinterpret_cast (vec_type, operands[0]),
|
||||
build_reinterpret_cast (vec_type, operands[0]), mask_vec);
|
||||
|
||||
tree cleared = build2 (BIT_AND_EXPR, vec_type, perm, and_mask_vec);
|
||||
|
||||
size_t s = int_size_in_bytes (TREE_TYPE (cleared)) * BITS_PER_UNIT;
|
||||
tree raw_type = build_nonstandard_integer_type (s, true);
|
||||
|
||||
tree as_int = build_reinterpret_cast (raw_type, cleared);
|
||||
|
||||
if (int_size_in_bytes (src_element_type) < 4)
|
||||
{
|
||||
if (INTEGRAL_TYPE_P (src_element_type))
|
||||
return extend_int (as_int, uint32_type_node, src_element_type);
|
||||
}
|
||||
return as_int;
|
||||
}
|
||||
|
||||
/* Packs (inserts) a scalar element in OPERANDS[1]
|
||||
to the vector in OPERANDS[0] at element position defined by
|
||||
OPERANDS[2]. */
|
||||
|
||||
tree
|
||||
brig_basic_inst_handler::build_pack (tree_stl_vec &operands)
|
||||
{
|
||||
/* Implement using a bit level insertion.
|
||||
TODO: Reuse this for implementing 'bitinsert'
|
||||
without a builtin call. */
|
||||
|
||||
size_t ecount = TYPE_VECTOR_SUBPARTS (TREE_TYPE (operands[0]));
|
||||
size_t vecsize = int_size_in_bytes (TREE_TYPE (operands[0])) * BITS_PER_UNIT;
|
||||
tree wide_type = build_nonstandard_integer_type (vecsize, 1);
|
||||
|
||||
tree src_vect = build_reinterpret_cast (wide_type, operands[0]);
|
||||
src_vect = add_temp_var ("src_vect", src_vect);
|
||||
|
||||
tree scalar = operands[1];
|
||||
scalar = add_temp_var ("scalar", convert_to_integer (wide_type, scalar));
|
||||
|
||||
tree pos = operands[2];
|
||||
|
||||
/* The upper bits of the position can contain garbage.
|
||||
Zero them for well-defined semantics. */
|
||||
tree t = build2 (BIT_AND_EXPR, TREE_TYPE (pos), operands[2],
|
||||
build_int_cstu (TREE_TYPE (pos), ecount - 1));
|
||||
pos = add_temp_var ("pos", convert (wide_type, t));
|
||||
|
||||
tree element_type = TREE_TYPE (TREE_TYPE (operands[0]));
|
||||
size_t element_width = int_size_in_bytes (element_type) * BITS_PER_UNIT;
|
||||
tree ewidth = build_int_cstu (wide_type, element_width);
|
||||
|
||||
tree bitoffset = build2 (MULT_EXPR, wide_type, ewidth, pos);
|
||||
bitoffset = add_temp_var ("offset", bitoffset);
|
||||
|
||||
uint64_t mask_int
|
||||
= element_width == 64 ? (uint64_t) -1 : ((uint64_t) 1 << element_width) - 1;
|
||||
|
||||
tree mask = build_int_cstu (wide_type, mask_int);
|
||||
|
||||
mask = add_temp_var ("mask", convert_to_integer (wide_type, mask));
|
||||
|
||||
tree clearing_mask
|
||||
= build1 (BIT_NOT_EXPR, wide_type,
|
||||
build2 (LSHIFT_EXPR, wide_type, mask, bitoffset));
|
||||
|
||||
tree zeroed_element
|
||||
= build2 (BIT_AND_EXPR, wide_type, src_vect, clearing_mask);
|
||||
|
||||
/* TODO: Is the AND necessary: does HSA define what
|
||||
happens if the upper bits in the inserted element are not
|
||||
zero? */
|
||||
tree element_in_position
|
||||
= build2 (LSHIFT_EXPR, wide_type,
|
||||
build2 (BIT_AND_EXPR, wide_type, scalar, mask), bitoffset);
|
||||
|
||||
tree inserted
|
||||
= build2 (BIT_IOR_EXPR, wide_type, zeroed_element, element_in_position);
|
||||
return inserted;
|
||||
}
|
||||
|
||||
/* Implement the unpack{lo,hi}. BRIG_OPCODE should tell which one and
|
||||
ARITH_TYPE describe the type of the vector arithmetics.
|
||||
OPERANDS[0] and OPERANDS[1] are the input vectors. */
|
||||
|
||||
tree
|
||||
brig_basic_inst_handler::build_unpack_lo_or_hi (BrigOpcode16_t brig_opcode,
|
||||
tree arith_type,
|
||||
tree_stl_vec &operands)
|
||||
{
|
||||
tree element_type = get_unsigned_int_type (TREE_TYPE (arith_type));
|
||||
tree mask_vec_type
|
||||
= build_vector_type (element_type, TYPE_VECTOR_SUBPARTS (arith_type));
|
||||
|
||||
size_t element_count = TYPE_VECTOR_SUBPARTS (arith_type);
|
||||
vec<constructor_elt, va_gc> *input_mask_vals = NULL;
|
||||
|
||||
size_t offset = (brig_opcode == BRIG_OPCODE_UNPACKLO) ? 0 : element_count / 2;
|
||||
|
||||
for (size_t i = 0; i < element_count / 2; ++i)
|
||||
{
|
||||
CONSTRUCTOR_APPEND_ELT (input_mask_vals, NULL_TREE,
|
||||
build_int_cst (element_type, offset + i));
|
||||
CONSTRUCTOR_APPEND_ELT (input_mask_vals, NULL_TREE,
|
||||
build_int_cst (element_type,
|
||||
offset + i + element_count));
|
||||
}
|
||||
|
||||
tree mask_vec = build_constructor (mask_vec_type, input_mask_vals);
|
||||
|
||||
tree perm = build3 (VEC_PERM_EXPR, TREE_TYPE (operands[0]), operands[0],
|
||||
operands[1], mask_vec);
|
||||
return perm;
|
||||
}
|
||||
|
||||
/* Builds a basic instruction expression from a BRIG instruction. BRIG_OPCODE
|
||||
is the opcode, BRIG_TYPE the brig type of the instruction, ARITH_TYPE the
|
||||
desired tree type for the instruction, and OPERANDS the instruction's
|
||||
input operands already converted to tree nodes. */
|
||||
|
||||
tree
|
||||
brig_basic_inst_handler::build_inst_expr (BrigOpcode16_t brig_opcode,
|
||||
BrigType16_t brig_type,
|
||||
tree arith_type,
|
||||
tree_stl_vec &operands)
|
||||
{
|
||||
tree_code opcode = get_tree_code_for_hsa_opcode (brig_opcode, brig_type);
|
||||
|
||||
BrigType16_t inner_type = brig_type & BRIG_TYPE_BASE_MASK;
|
||||
|
||||
tree instr_inner_type
|
||||
= VECTOR_TYPE_P (arith_type) ? TREE_TYPE (arith_type) : arith_type;
|
||||
|
||||
if (opcode == RSHIFT_EXPR || opcode == LSHIFT_EXPR)
|
||||
{
|
||||
/* HSA defines modulo/clipping behavior for shift amounts larger
|
||||
than the bit width, while tree.def leaves it undefined.
|
||||
We need to mask the upper bits to ensure the defined behavior. */
|
||||
tree scalar_mask
|
||||
= build_int_cst (instr_inner_type,
|
||||
gccbrig_hsa_type_bit_size (inner_type) - 1);
|
||||
|
||||
tree mask = VECTOR_TYPE_P (arith_type)
|
||||
? build_vector_from_val (arith_type, scalar_mask)
|
||||
: scalar_mask;
|
||||
|
||||
/* The shift amount is a scalar, broadcast it to produce
|
||||
a vector shift. */
|
||||
if (VECTOR_TYPE_P (arith_type))
|
||||
operands[1] = build_vector_from_val (arith_type, operands[1]);
|
||||
operands[1] = build2 (BIT_AND_EXPR, arith_type, operands[1], mask);
|
||||
}
|
||||
|
||||
size_t input_count = operands.size ();
|
||||
size_t output_count = gccbrig_hsa_opcode_op_output_p (brig_opcode, 0) ?
|
||||
1 : 0;
|
||||
|
||||
if (opcode == TREE_LIST)
|
||||
{
|
||||
/* There was no direct GENERIC opcode for the instruction;
|
||||
try to emulate it with a chain of GENERIC nodes. */
|
||||
if (brig_opcode == BRIG_OPCODE_MAD || brig_opcode == BRIG_OPCODE_MAD24)
|
||||
{
|
||||
/* There doesn't seem to be a "standard" MAD built-in in gcc so let's
|
||||
use a chain of multiply + add for now (double rounding method).
|
||||
It should be easier for optimizers than a custom built-in call
|
||||
WIDEN_MULT_EXPR is close, but requires a double size result
|
||||
type. */
|
||||
tree mult_res
|
||||
= build2 (MULT_EXPR, arith_type, operands[0], operands[1]);
|
||||
return build2 (PLUS_EXPR, arith_type, mult_res, operands[2]);
|
||||
}
|
||||
else if (brig_opcode == BRIG_OPCODE_MAD24HI)
|
||||
{
|
||||
tree mult_res
|
||||
= build2 (MULT_HIGHPART_EXPR, arith_type, operands[0], operands[1]);
|
||||
return build2 (PLUS_EXPR, arith_type, mult_res, operands[2]);
|
||||
}
|
||||
else if (brig_opcode == BRIG_OPCODE_SHUFFLE)
|
||||
{
|
||||
return build_shuffle (arith_type, operands);
|
||||
}
|
||||
else if (brig_opcode == BRIG_OPCODE_UNPACKLO
|
||||
|| brig_opcode == BRIG_OPCODE_UNPACKHI)
|
||||
{
|
||||
return build_unpack_lo_or_hi (brig_opcode, arith_type, operands);
|
||||
}
|
||||
else if (brig_opcode == BRIG_OPCODE_UNPACK)
|
||||
{
|
||||
return build_unpack (operands);
|
||||
}
|
||||
else if (brig_opcode == BRIG_OPCODE_PACK)
|
||||
{
|
||||
return build_pack (operands);
|
||||
}
|
||||
else if (brig_opcode == BRIG_OPCODE_NRSQRT)
|
||||
{
|
||||
/* Implement as 1.0/sqrt (x) and assume gcc instruction selects to
|
||||
native ISA other than a division, if available.
|
||||
TODO: this will happen only with unsafe math optimizations
|
||||
on which cannot be used in general to remain HSAIL compliant.
|
||||
Perhaps a builtin call would be better option here. */
|
||||
return build2 (RDIV_EXPR, arith_type, build_one_cst (arith_type),
|
||||
expand_or_call_builtin (BRIG_OPCODE_SQRT, brig_type,
|
||||
arith_type, operands));
|
||||
}
|
||||
else if (brig_opcode == BRIG_OPCODE_NRCP)
|
||||
{
|
||||
/* Implement as 1.0/x and assume gcc instruction selects to
|
||||
native ISA other than a division, if available. */
|
||||
return build2 (RDIV_EXPR, arith_type, build_one_cst (arith_type),
|
||||
operands[0]);
|
||||
}
|
||||
else if (brig_opcode == BRIG_OPCODE_LANEID
|
||||
|| brig_opcode == BRIG_OPCODE_MAXWAVEID
|
||||
|| brig_opcode == BRIG_OPCODE_WAVEID)
|
||||
{
|
||||
/* Assuming WAVESIZE 1 (for now), therefore LANEID, WAVEID and
|
||||
MAXWAVEID always return 0. */
|
||||
return build_zero_cst (arith_type);
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else if (opcode == CALL_EXPR)
|
||||
return expand_or_call_builtin (brig_opcode, brig_type, arith_type,
|
||||
operands);
|
||||
else if (output_count == 1)
|
||||
{
|
||||
if (input_count == 1)
|
||||
{
|
||||
if (opcode == MODIFY_EXPR)
|
||||
return operands[0];
|
||||
else
|
||||
return build1 (opcode, arith_type, operands[0]);
|
||||
}
|
||||
else if (input_count == 2)
|
||||
return build2 (opcode, arith_type, operands[0], operands[1]);
|
||||
else if (input_count == 3)
|
||||
return build3 (opcode, arith_type, operands[0], operands[1],
|
||||
operands[2]);
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Handles the basic instructions, including packed instructions. Deals
|
||||
with the different packing modes by unpacking/packing the wanted
|
||||
elements. Delegates most of the instruction cases to build_inst_expr(). */
|
||||
|
||||
size_t
|
||||
brig_basic_inst_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigInstBase *brig_inst = (const BrigInstBase *) base;
|
||||
|
||||
tree_stl_vec operands = build_operands (*brig_inst);
|
||||
|
||||
size_t output_count
|
||||
= gccbrig_hsa_opcode_op_output_p (brig_inst->opcode, 0) ? 1 : 0;
|
||||
size_t input_count
|
||||
= operands.size () == 0 ? 0 : (operands.size () - output_count);
|
||||
|
||||
gcc_assert (output_count == 0 || output_count == 1);
|
||||
|
||||
tree_stl_vec::iterator first_input_i = operands.begin ();
|
||||
if (output_count > 0 && operands.size () > 0)
|
||||
++first_input_i;
|
||||
|
||||
tree_stl_vec in_operands;
|
||||
in_operands.assign (first_input_i, operands.end ());
|
||||
|
||||
BrigType16_t brig_inst_type = brig_inst->type;
|
||||
|
||||
if (brig_inst->opcode == BRIG_OPCODE_NOP)
|
||||
return base->byteCount;
|
||||
else if (brig_inst->opcode == BRIG_OPCODE_FIRSTBIT
|
||||
|| brig_inst->opcode == BRIG_OPCODE_LASTBIT
|
||||
|| brig_inst->opcode == BRIG_OPCODE_SAD)
|
||||
/* These instructions are reported to be always 32b in HSAIL, but we want
|
||||
to treat them according to their input argument's type to select the
|
||||
correct instruction/builtin. */
|
||||
brig_inst_type
|
||||
= gccbrig_tree_type_to_hsa_type (TREE_TYPE (in_operands[0]));
|
||||
|
||||
tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst_type);
|
||||
|
||||
if (!instr_type)
|
||||
{
|
||||
gcc_unreachable ();
|
||||
return base->byteCount;
|
||||
}
|
||||
|
||||
bool is_vec_instr = hsa_type_packed_p (brig_inst_type);
|
||||
|
||||
size_t element_size_bits;
|
||||
size_t element_count;
|
||||
|
||||
if (is_vec_instr)
|
||||
{
|
||||
BrigType16_t brig_element_type = brig_inst_type & BRIG_TYPE_BASE_MASK;
|
||||
element_size_bits = gccbrig_hsa_type_bit_size (brig_element_type);
|
||||
element_count = gccbrig_hsa_type_bit_size (brig_inst_type)
|
||||
/ gccbrig_hsa_type_bit_size (brig_element_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
element_size_bits = gccbrig_hsa_type_bit_size (brig_inst_type);
|
||||
element_count = 1;
|
||||
}
|
||||
|
||||
/* The actual arithmetics type that should be performed with the
|
||||
operation. This is not always the same as the original BRIG
|
||||
opcode's type due to implicit conversions of storage-only f16. */
|
||||
tree arith_type = gccbrig_is_bit_operation (brig_inst->opcode)
|
||||
? gccbrig_tree_type_for_hsa_type (brig_inst_type)
|
||||
: get_tree_expr_type_for_hsa_type (brig_inst_type);
|
||||
|
||||
tree instr_expr = NULL_TREE;
|
||||
|
||||
BrigPack8_t p = BRIG_PACK_NONE;
|
||||
if (brig_inst->base.kind == BRIG_KIND_INST_MOD)
|
||||
p = ((const BrigInstMod *) brig_inst)->pack;
|
||||
else if (brig_inst->base.kind == BRIG_KIND_INST_CMP)
|
||||
p = ((const BrigInstCmp *) brig_inst)->pack;
|
||||
|
||||
if (p == BRIG_PACK_PS || p == BRIG_PACK_PSSAT)
|
||||
in_operands[1] = build_lower_element_broadcast (in_operands[1]);
|
||||
else if (p == BRIG_PACK_SP || p == BRIG_PACK_SPSAT)
|
||||
in_operands[0] = build_lower_element_broadcast (in_operands[0]);
|
||||
|
||||
tree_code opcode
|
||||
= get_tree_code_for_hsa_opcode (brig_inst->opcode, brig_inst_type);
|
||||
|
||||
if (p >= BRIG_PACK_PPSAT && p <= BRIG_PACK_PSAT)
|
||||
{
|
||||
scalarized_sat_arithmetics sat_arith (*brig_inst);
|
||||
gcc_assert (input_count == 2);
|
||||
instr_expr = sat_arith (*this, in_operands[0], in_operands[1]);
|
||||
}
|
||||
else if (opcode == RETURN_EXPR)
|
||||
{
|
||||
if (m_parent.m_cf->m_is_kernel)
|
||||
{
|
||||
tree goto_stmt
|
||||
= build1 (GOTO_EXPR, void_type_node, m_parent.m_cf->m_exit_label);
|
||||
m_parent.m_cf->append_statement (goto_stmt);
|
||||
return base->byteCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_parent.m_cf->append_return_stmt ();
|
||||
return base->byteCount;
|
||||
}
|
||||
}
|
||||
else if (opcode == MULT_HIGHPART_EXPR &&
|
||||
is_vec_instr && element_size_bits < 64)
|
||||
{
|
||||
/* MULT_HIGHPART_EXPR works only on target dependent vector sizes and
|
||||
even the scalars do not seem to work at least for char elements.
|
||||
|
||||
Let's fall back to scalarization and promotion of the vector elements
|
||||
to larger types with the MULHI computed as a regular MUL.
|
||||
MULHI for 2x64b seems to work with the Intel CPUs I've tested so
|
||||
that is passed on for vector processing so there is no need for
|
||||
128b scalar arithmetics.
|
||||
|
||||
This is not modular as these type of things do not belong to the
|
||||
frontend, there should be a legalization phase before the backend
|
||||
that figures out the best way to compute the MULHI for any
|
||||
integer vector datatype.
|
||||
|
||||
TODO: promote to larger vector types instead. For example
|
||||
MULT_HIGHPART_EXPR with s8x8 doesn't work, but s16x8 seems to at least
|
||||
with my x86-64.
|
||||
*/
|
||||
tree_stl_vec operand0_elements;
|
||||
if (input_count > 0)
|
||||
unpack (in_operands[0], operand0_elements);
|
||||
|
||||
tree_stl_vec operand1_elements;
|
||||
if (input_count > 1)
|
||||
unpack (in_operands[1], operand1_elements);
|
||||
|
||||
tree_stl_vec result_elements;
|
||||
|
||||
tree scalar_type = TREE_TYPE (arith_type);
|
||||
BrigType16_t element_type = brig_inst_type & BRIG_TYPE_BASE_MASK;
|
||||
tree promoted_type = short_integer_type_node;
|
||||
switch (element_type)
|
||||
{
|
||||
case BRIG_TYPE_S8:
|
||||
promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_S16);
|
||||
break;
|
||||
case BRIG_TYPE_U8:
|
||||
promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U16);
|
||||
break;
|
||||
case BRIG_TYPE_S16:
|
||||
promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_S32);
|
||||
break;
|
||||
case BRIG_TYPE_U16:
|
||||
promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U32);
|
||||
break;
|
||||
case BRIG_TYPE_S32:
|
||||
promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_S64);
|
||||
break;
|
||||
case BRIG_TYPE_U32:
|
||||
promoted_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U64);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
size_t promoted_type_size = int_size_in_bytes (promoted_type) * 8;
|
||||
|
||||
for (size_t i = 0; i < TYPE_VECTOR_SUBPARTS (arith_type); ++i)
|
||||
{
|
||||
tree operand0 = convert (promoted_type, operand0_elements.at (i));
|
||||
tree operand1 = convert (promoted_type, operand1_elements.at (i));
|
||||
|
||||
tree scalar_expr
|
||||
= build2 (MULT_EXPR, promoted_type, operand0, operand1);
|
||||
|
||||
scalar_expr
|
||||
= build2 (RSHIFT_EXPR, promoted_type, scalar_expr,
|
||||
build_int_cstu (promoted_type, promoted_type_size / 2));
|
||||
|
||||
result_elements.push_back (convert (scalar_type, scalar_expr));
|
||||
}
|
||||
instr_expr = pack (result_elements);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 'class' is always of b1 type, let's consider it by its
|
||||
float type when building the instruction to find the
|
||||
correct builtin. */
|
||||
if (brig_inst->opcode == BRIG_OPCODE_CLASS)
|
||||
brig_inst_type = ((const BrigInstSourceType *) base)->sourceType;
|
||||
instr_expr = build_inst_expr (brig_inst->opcode, brig_inst_type,
|
||||
arith_type, in_operands);
|
||||
}
|
||||
|
||||
if (instr_expr == NULL_TREE)
|
||||
{
|
||||
gcc_unreachable ();
|
||||
return base->byteCount;
|
||||
}
|
||||
|
||||
if (p == BRIG_PACK_SS || p == BRIG_PACK_S || p == BRIG_PACK_SSSAT
|
||||
|| p == BRIG_PACK_SSAT)
|
||||
{
|
||||
/* In case of _s_ or _ss_, select only the lowest element
|
||||
from the new input to the output. We could extract
|
||||
the element and use a scalar operation, but try
|
||||
to keep data in vector registers as much as possible
|
||||
to avoid copies between scalar and vector datapaths. */
|
||||
tree old_value;
|
||||
tree half_storage_type = gccbrig_tree_type_for_hsa_type (brig_inst_type);
|
||||
bool is_fp16_operation
|
||||
= (brig_inst_type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16
|
||||
&& !gccbrig_is_bit_operation (brig_inst->opcode);
|
||||
|
||||
if (is_fp16_operation)
|
||||
old_value = build_h2f_conversion
|
||||
(build_reinterpret_cast (half_storage_type, operands[0]));
|
||||
else
|
||||
old_value
|
||||
= build_reinterpret_cast (TREE_TYPE (instr_expr), operands[0]);
|
||||
|
||||
size_t esize = is_fp16_operation ? 32 : element_size_bits;
|
||||
|
||||
/* Construct a permutation mask where other elements than the lowest one
|
||||
is picked from the old_value. */
|
||||
tree mask_inner_type = build_nonstandard_integer_type (esize, 1);
|
||||
vec<constructor_elt, va_gc> *constructor_vals = NULL;
|
||||
for (size_t i = 0; i < element_count; ++i)
|
||||
{
|
||||
tree cst;
|
||||
|
||||
if (i == 0)
|
||||
cst = build_int_cstu (mask_inner_type, element_count);
|
||||
else
|
||||
cst = build_int_cstu (mask_inner_type, i);
|
||||
CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, cst);
|
||||
}
|
||||
tree mask_vec_type = build_vector_type (mask_inner_type, element_count);
|
||||
tree mask = build_vector_from_ctor (mask_vec_type, constructor_vals);
|
||||
|
||||
tree new_value = create_tmp_var (TREE_TYPE (instr_expr), "new_output");
|
||||
tree assign
|
||||
= build2 (MODIFY_EXPR, TREE_TYPE (instr_expr), new_value, instr_expr);
|
||||
m_parent.m_cf->append_statement (assign);
|
||||
|
||||
instr_expr
|
||||
= build3 (VEC_PERM_EXPR, arith_type, old_value, new_value, mask);
|
||||
|
||||
tree lower_output = create_tmp_var (TREE_TYPE (instr_expr), "s_output");
|
||||
tree assign_lower = build2 (MODIFY_EXPR, TREE_TYPE (instr_expr),
|
||||
lower_output, instr_expr);
|
||||
m_parent.m_cf->append_statement (assign_lower);
|
||||
instr_expr = lower_output;
|
||||
}
|
||||
|
||||
if (output_count == 1)
|
||||
build_output_assignment (*brig_inst, operands[0], instr_expr);
|
||||
else
|
||||
m_parent.m_cf->append_statement (instr_expr);
|
||||
return base->byteCount;
|
||||
}
|
||||
|
||||
/* Create an expression that broadcasts the lowest element of the
|
||||
vector in VEC_OPERAND to all elements of the returned vector. */
|
||||
|
||||
tree
|
||||
brig_basic_inst_handler::build_lower_element_broadcast (tree vec_operand)
|
||||
{
|
||||
/* Build the broadcast using shuffle because there's no
|
||||
direct broadcast in GENERIC and this way there's no need for
|
||||
a separate extract of the lowest element. */
|
||||
tree element_type = TREE_TYPE (TREE_TYPE (vec_operand));
|
||||
size_t esize = 8 * int_size_in_bytes (element_type);
|
||||
|
||||
size_t element_count = TYPE_VECTOR_SUBPARTS (TREE_TYPE (vec_operand));
|
||||
tree mask_inner_type = build_nonstandard_integer_type (esize, 1);
|
||||
vec<constructor_elt, va_gc> *constructor_vals = NULL;
|
||||
|
||||
/* Construct the mask. */
|
||||
for (size_t i = 0; i < element_count; ++i)
|
||||
{
|
||||
tree cst = build_int_cstu (mask_inner_type, element_count);
|
||||
CONSTRUCTOR_APPEND_ELT (constructor_vals, NULL_TREE, cst);
|
||||
}
|
||||
tree mask_vec_type = build_vector_type (mask_inner_type, element_count);
|
||||
tree mask = build_vector_from_ctor (mask_vec_type, constructor_vals);
|
||||
|
||||
return build3 (VEC_PERM_EXPR, TREE_TYPE (vec_operand), vec_operand,
|
||||
vec_operand, mask);
|
||||
}
|
||||
|
||||
/* Returns the tree code that should be used to implement the given
|
||||
HSA instruction opcode (BRIG_OPCODE) for the given type of instruction
|
||||
(BRIG_TYPE). In case the opcode cannot be mapped to a TREE node directly,
|
||||
returns TREE_LIST (if it can be emulated with a simple chain of tree
|
||||
nodes) or CALL_EXPR if the opcode should be implemented using a builtin
|
||||
call. */
|
||||
|
||||
tree_code
|
||||
brig_basic_inst_handler::get_tree_code_for_hsa_opcode
|
||||
(BrigOpcode16_t brig_opcode, BrigType16_t brig_type) const
|
||||
{
|
||||
BrigType16_t brig_inner_type = brig_type & BRIG_TYPE_BASE_MASK;
|
||||
switch (brig_opcode)
|
||||
{
|
||||
case BRIG_OPCODE_NOP:
|
||||
return NOP_EXPR;
|
||||
case BRIG_OPCODE_ADD:
|
||||
return PLUS_EXPR;
|
||||
case BRIG_OPCODE_CMOV:
|
||||
if (brig_inner_type == brig_type)
|
||||
return COND_EXPR;
|
||||
else
|
||||
return VEC_COND_EXPR;
|
||||
case BRIG_OPCODE_SUB:
|
||||
return MINUS_EXPR;
|
||||
case BRIG_OPCODE_MUL:
|
||||
case BRIG_OPCODE_MUL24:
|
||||
return MULT_EXPR;
|
||||
case BRIG_OPCODE_MULHI:
|
||||
case BRIG_OPCODE_MUL24HI:
|
||||
return MULT_HIGHPART_EXPR;
|
||||
case BRIG_OPCODE_DIV:
|
||||
if (gccbrig_is_float_type (brig_inner_type))
|
||||
return RDIV_EXPR;
|
||||
else
|
||||
return TRUNC_DIV_EXPR;
|
||||
case BRIG_OPCODE_NEG:
|
||||
return NEGATE_EXPR;
|
||||
case BRIG_OPCODE_MIN:
|
||||
if (gccbrig_is_float_type (brig_inner_type))
|
||||
return CALL_EXPR;
|
||||
else
|
||||
return MIN_EXPR;
|
||||
case BRIG_OPCODE_MAX:
|
||||
if (gccbrig_is_float_type (brig_inner_type))
|
||||
return CALL_EXPR;
|
||||
else
|
||||
return MAX_EXPR;
|
||||
case BRIG_OPCODE_FMA:
|
||||
return FMA_EXPR;
|
||||
case BRIG_OPCODE_ABS:
|
||||
return ABS_EXPR;
|
||||
case BRIG_OPCODE_SHL:
|
||||
return LSHIFT_EXPR;
|
||||
case BRIG_OPCODE_SHR:
|
||||
return RSHIFT_EXPR;
|
||||
case BRIG_OPCODE_OR:
|
||||
return BIT_IOR_EXPR;
|
||||
case BRIG_OPCODE_XOR:
|
||||
return BIT_XOR_EXPR;
|
||||
case BRIG_OPCODE_AND:
|
||||
return BIT_AND_EXPR;
|
||||
case BRIG_OPCODE_NOT:
|
||||
return BIT_NOT_EXPR;
|
||||
case BRIG_OPCODE_RET:
|
||||
return RETURN_EXPR;
|
||||
case BRIG_OPCODE_MOV:
|
||||
case BRIG_OPCODE_LDF:
|
||||
return MODIFY_EXPR;
|
||||
case BRIG_OPCODE_LD:
|
||||
case BRIG_OPCODE_ST:
|
||||
return MEM_REF;
|
||||
case BRIG_OPCODE_BR:
|
||||
return GOTO_EXPR;
|
||||
case BRIG_OPCODE_REM:
|
||||
if (brig_type == BRIG_TYPE_U64 || brig_type == BRIG_TYPE_U32)
|
||||
return TRUNC_MOD_EXPR;
|
||||
else
|
||||
return CALL_EXPR;
|
||||
case BRIG_OPCODE_NRCP:
|
||||
case BRIG_OPCODE_NRSQRT:
|
||||
/* Implement as 1/f (x). gcc should pattern detect that and
|
||||
use a native instruction, if available, for it. */
|
||||
return TREE_LIST;
|
||||
case BRIG_OPCODE_FLOOR:
|
||||
case BRIG_OPCODE_CEIL:
|
||||
case BRIG_OPCODE_SQRT:
|
||||
case BRIG_OPCODE_NSQRT:
|
||||
case BRIG_OPCODE_RINT:
|
||||
case BRIG_OPCODE_TRUNC:
|
||||
case BRIG_OPCODE_POPCOUNT:
|
||||
case BRIG_OPCODE_COPYSIGN:
|
||||
case BRIG_OPCODE_NCOS:
|
||||
case BRIG_OPCODE_NSIN:
|
||||
case BRIG_OPCODE_NLOG2:
|
||||
case BRIG_OPCODE_NEXP2:
|
||||
case BRIG_OPCODE_NFMA:
|
||||
/* Class has type B1 regardless of the float type, thus
|
||||
the below builtin map search cannot find it. */
|
||||
case BRIG_OPCODE_CLASS:
|
||||
case BRIG_OPCODE_WORKITEMABSID:
|
||||
return CALL_EXPR;
|
||||
default:
|
||||
|
||||
/* Some BRIG opcodes can use the same builtins for unsigned and
|
||||
signed types. Force these cases to unsigned types.
|
||||
*/
|
||||
|
||||
if (brig_opcode == BRIG_OPCODE_BORROW
|
||||
|| brig_opcode == BRIG_OPCODE_CARRY
|
||||
|| brig_opcode == BRIG_OPCODE_LASTBIT
|
||||
|| brig_opcode == BRIG_OPCODE_BITINSERT)
|
||||
{
|
||||
if (brig_type == BRIG_TYPE_S32)
|
||||
brig_type = BRIG_TYPE_U32;
|
||||
else if (brig_type == BRIG_TYPE_S64)
|
||||
brig_type = BRIG_TYPE_U64;
|
||||
}
|
||||
|
||||
|
||||
builtin_map::const_iterator i
|
||||
= s_custom_builtins.find (std::make_pair (brig_opcode, brig_type));
|
||||
if (i != s_custom_builtins.end ())
|
||||
return CALL_EXPR;
|
||||
else if (s_custom_builtins.find
|
||||
(std::make_pair (brig_opcode, brig_inner_type))
|
||||
!= s_custom_builtins.end ())
|
||||
return CALL_EXPR;
|
||||
if (brig_inner_type == BRIG_TYPE_F16
|
||||
&& s_custom_builtins.find
|
||||
(std::make_pair (brig_opcode, BRIG_TYPE_F32))
|
||||
!= s_custom_builtins.end ())
|
||||
return CALL_EXPR;
|
||||
break;
|
||||
}
|
||||
return TREE_LIST; /* Emulate using a chain of nodes. */
|
||||
}
|
221
gcc/brig/brigfrontend/brig-branch-inst-handler.cc
Normal file
221
gcc/brig/brigfrontend/brig-branch-inst-handler.cc
Normal file
|
@ -0,0 +1,221 @@
|
|||
/* brig-branch-inst-handler.cc -- brig branch instruction handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
|
||||
#include "errors.h"
|
||||
#include "brig-util.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "print-tree.h"
|
||||
#include "vec.h"
|
||||
#include "fold-const.h"
|
||||
|
||||
size_t
|
||||
brig_branch_inst_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigInstBase *brig_inst
|
||||
= (const BrigInstBase *) &((const BrigInstBasic *) base)->base;
|
||||
|
||||
if (brig_inst->opcode == BRIG_OPCODE_CALL)
|
||||
{
|
||||
const BrigData *operand_entries
|
||||
= m_parent.get_brig_data_entry (brig_inst->operands);
|
||||
tree func_ref = NULL_TREE;
|
||||
vec<tree, va_gc> *out_args;
|
||||
vec_alloc (out_args, 1);
|
||||
vec<tree, va_gc> *in_args;
|
||||
vec_alloc (in_args, 4);
|
||||
|
||||
size_t operand_count = operand_entries->byteCount / 4;
|
||||
gcc_assert (operand_count < 4);
|
||||
|
||||
for (size_t i = 0; i < operand_count; ++i)
|
||||
{
|
||||
uint32_t operand_offset
|
||||
= ((const uint32_t *) &operand_entries->bytes)[i];
|
||||
const BrigBase *operand_data
|
||||
= m_parent.get_brig_operand_entry (operand_offset);
|
||||
if (i == 1)
|
||||
{
|
||||
gcc_assert (operand_data->kind == BRIG_KIND_OPERAND_CODE_REF);
|
||||
func_ref = build_tree_operand (*brig_inst, *operand_data);
|
||||
continue;
|
||||
}
|
||||
gcc_assert (operand_data->kind == BRIG_KIND_OPERAND_CODE_LIST);
|
||||
const BrigOperandCodeList *codelist
|
||||
= (const BrigOperandCodeList *) operand_data;
|
||||
const BrigData *data
|
||||
= m_parent.get_brig_data_entry (codelist->elements);
|
||||
|
||||
size_t bytes = data->byteCount;
|
||||
const BrigOperandOffset32_t *operand_ptr
|
||||
= (const BrigOperandOffset32_t *) data->bytes;
|
||||
|
||||
vec<tree, va_gc> *args = i == 0 ? out_args : in_args;
|
||||
|
||||
while (bytes > 0)
|
||||
{
|
||||
BrigOperandOffset32_t offset = *operand_ptr;
|
||||
const BrigBase *code_element
|
||||
= m_parent.get_brig_code_entry (offset);
|
||||
gcc_assert (code_element->kind == BRIG_KIND_DIRECTIVE_VARIABLE);
|
||||
const BrigDirectiveVariable *brig_var
|
||||
= (const BrigDirectiveVariable *) code_element;
|
||||
tree var = m_parent.m_cf->arg_variable (brig_var);
|
||||
|
||||
if (brig_var->type & BRIG_TYPE_ARRAY)
|
||||
{
|
||||
/* Array return values are passed as the first argument. */
|
||||
args = in_args;
|
||||
/* Pass pointer to the element zero and use its element zero
|
||||
as the base address. */
|
||||
tree etype = TREE_TYPE (TREE_TYPE (var));
|
||||
tree ptype = build_pointer_type (etype);
|
||||
tree element_zero
|
||||
= build4 (ARRAY_REF, etype, var, integer_zero_node,
|
||||
NULL_TREE, NULL_TREE);
|
||||
var = build1 (ADDR_EXPR, ptype, element_zero);
|
||||
}
|
||||
|
||||
gcc_assert (var != NULL_TREE);
|
||||
vec_safe_push (args, var);
|
||||
++operand_ptr;
|
||||
bytes -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
gcc_assert (func_ref != NULL_TREE);
|
||||
gcc_assert (out_args->length () == 0 || out_args->length () == 1);
|
||||
|
||||
tree ret_val_type = void_type_node;
|
||||
tree ret_val = NULL_TREE;
|
||||
if (out_args->length () == 1)
|
||||
{
|
||||
ret_val = (*out_args)[0];
|
||||
ret_val_type = TREE_TYPE (ret_val);
|
||||
}
|
||||
|
||||
/* Pass the hidden kernel arguments along to the called functions as
|
||||
they might call builtins that need them or access group/private
|
||||
memory. */
|
||||
|
||||
vec_safe_push (in_args, m_parent.m_cf->m_context_arg);
|
||||
vec_safe_push (in_args, m_parent.m_cf->m_group_base_arg);
|
||||
vec_safe_push (in_args, m_parent.m_cf->m_private_base_arg);
|
||||
|
||||
tree call = build_call_vec (ret_val_type, build_fold_addr_expr (func_ref),
|
||||
in_args);
|
||||
TREE_NOTHROW (func_ref) = 1;
|
||||
TREE_NOTHROW (call) = 1;
|
||||
|
||||
if (ret_val != NULL_TREE)
|
||||
{
|
||||
TREE_ADDRESSABLE (ret_val) = 1;
|
||||
tree result_assign
|
||||
= build2 (MODIFY_EXPR, TREE_TYPE (ret_val), ret_val, call);
|
||||
m_parent.m_cf->append_statement (result_assign);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_parent.m_cf->append_statement (call);
|
||||
}
|
||||
|
||||
m_parent.m_cf->m_has_unexpanded_dp_builtins = false;
|
||||
m_parent.m_cf->m_called_functions.push_back (func_ref);
|
||||
|
||||
return base->byteCount;
|
||||
}
|
||||
|
||||
tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst->type);
|
||||
tree_stl_vec operands = build_operands (*brig_inst);
|
||||
|
||||
if (brig_inst->opcode == BRIG_OPCODE_BR)
|
||||
{
|
||||
tree goto_stmt = build1 (GOTO_EXPR, instr_type, operands[0]);
|
||||
m_parent.m_cf->append_statement (goto_stmt);
|
||||
}
|
||||
else if (brig_inst->opcode == BRIG_OPCODE_SBR)
|
||||
{
|
||||
tree select = operands[0];
|
||||
tree cases = operands[1];
|
||||
|
||||
tree switch_expr = build3 (SWITCH_EXPR, TREE_TYPE (select), select,
|
||||
NULL_TREE, NULL_TREE);
|
||||
|
||||
tree default_case
|
||||
= build_case_label (NULL_TREE, NULL_TREE,
|
||||
create_artificial_label (UNKNOWN_LOCATION));
|
||||
append_to_statement_list (default_case, &SWITCH_BODY (switch_expr));
|
||||
|
||||
tree default_jump
|
||||
= build1 (GOTO_EXPR, void_type_node, TREE_VEC_ELT (cases, 0));
|
||||
append_to_statement_list (default_jump, &SWITCH_BODY (switch_expr));
|
||||
|
||||
for (int c = 0; c < TREE_VEC_LENGTH (cases); ++c)
|
||||
{
|
||||
tree case_label
|
||||
= build_case_label (build_int_cst (integer_type_node, c), NULL_TREE,
|
||||
create_artificial_label (UNKNOWN_LOCATION));
|
||||
|
||||
append_to_statement_list (case_label, &SWITCH_BODY (switch_expr));
|
||||
|
||||
tree jump
|
||||
= build1 (GOTO_EXPR, void_type_node, TREE_VEC_ELT (cases, c));
|
||||
append_to_statement_list (jump, &SWITCH_BODY (switch_expr));
|
||||
}
|
||||
m_parent.m_cf->append_statement (switch_expr);
|
||||
}
|
||||
else if (brig_inst->opcode == BRIG_OPCODE_CBR)
|
||||
{
|
||||
tree condition = operands[0];
|
||||
tree target_goto = build1 (GOTO_EXPR, void_type_node, operands[1]);
|
||||
/* Represents the if..else as (condition)?(goto foo):(goto bar). */
|
||||
tree if_stmt
|
||||
= build3 (COND_EXPR, void_type_node, condition, target_goto, NULL_TREE);
|
||||
m_parent.m_cf->append_statement (if_stmt);
|
||||
}
|
||||
else if (brig_inst->opcode == BRIG_OPCODE_WAVEBARRIER)
|
||||
{
|
||||
/* WAVEBARRIER is a NOP when WAVESIZE = 1. */
|
||||
}
|
||||
else if (brig_inst->opcode == BRIG_OPCODE_BARRIER)
|
||||
{
|
||||
m_parent.m_cf->m_has_barriers = true;
|
||||
tree_stl_vec call_operands;
|
||||
/* FIXME. We should add attributes (are there suitable ones in gcc?) that
|
||||
ensure the barrier won't be duplicated or moved out of loops etc.
|
||||
Like the 'noduplicate' of LLVM. Same goes for fbarriers. */
|
||||
m_parent.m_cf->append_statement
|
||||
(expand_or_call_builtin (brig_inst->opcode, BRIG_TYPE_NONE, NULL_TREE,
|
||||
call_operands));
|
||||
}
|
||||
else if (brig_inst->opcode >= BRIG_OPCODE_ARRIVEFBAR
|
||||
&& brig_inst->opcode <= BRIG_OPCODE_WAITFBAR)
|
||||
{
|
||||
m_parent.m_cf->m_has_barriers = true;
|
||||
m_parent.m_cf->append_statement
|
||||
(expand_or_call_builtin (brig_inst->opcode, BRIG_TYPE_NONE,
|
||||
uint32_type_node, operands));
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
return base->byteCount;
|
||||
}
|
198
gcc/brig/brigfrontend/brig-cmp-inst-handler.cc
Normal file
198
gcc/brig/brigfrontend/brig-cmp-inst-handler.cc
Normal file
|
@ -0,0 +1,198 @@
|
|||
/* brig-cmp-inst-handler.cc -- brig cmp instruction handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "diagnostic.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "print-tree.h"
|
||||
#include "brig-util.h"
|
||||
#include "convert.h"
|
||||
|
||||
size_t
|
||||
brig_cmp_inst_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigInstBase *inst_base = (const BrigInstBase *) base;
|
||||
const BrigInstCmp *inst = (const BrigInstCmp *) base;
|
||||
|
||||
tree cmp_type = get_tree_expr_type_for_hsa_type (inst->sourceType);
|
||||
|
||||
/* The destination type to convert the comparison result to. */
|
||||
tree dest_type = gccbrig_tree_type_for_hsa_type (inst_base->type);
|
||||
|
||||
const bool is_fp16_dest
|
||||
= (inst_base->type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16;
|
||||
const bool is_boolean_dest
|
||||
= (inst_base->type & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_B1;
|
||||
|
||||
bool is_int_cmp = VECTOR_TYPE_P (cmp_type)
|
||||
? INTEGRAL_TYPE_P (TREE_TYPE (cmp_type))
|
||||
: INTEGRAL_TYPE_P (cmp_type);
|
||||
|
||||
/* The type for the GENERIC comparison. It should match the
|
||||
input operand width for vector comparisons, a boolean
|
||||
otherwise. */
|
||||
tree result_type = get_comparison_result_type (cmp_type);
|
||||
|
||||
/* Save the result as a boolean and extend/convert it to the
|
||||
wanted destination type. */
|
||||
tree expr = NULL_TREE;
|
||||
|
||||
std::vector<tree> operands = build_operands (*inst_base);
|
||||
|
||||
switch (inst->compare)
|
||||
{
|
||||
case BRIG_COMPARE_SEQ:
|
||||
case BRIG_COMPARE_EQ:
|
||||
expr = build2 (EQ_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SNE:
|
||||
case BRIG_COMPARE_NE:
|
||||
expr = build2 (NE_EXPR, result_type, operands[1], operands[2]);
|
||||
|
||||
if (!is_int_cmp)
|
||||
expr = build2 (BIT_AND_EXPR, TREE_TYPE (expr),
|
||||
expr,
|
||||
build2 (ORDERED_EXPR, result_type, operands[1],
|
||||
operands[2]));
|
||||
break;
|
||||
case BRIG_COMPARE_SLT:
|
||||
case BRIG_COMPARE_LT:
|
||||
expr = build2 (LT_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SLE:
|
||||
case BRIG_COMPARE_LE:
|
||||
expr = build2 (LE_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SGT:
|
||||
case BRIG_COMPARE_GT:
|
||||
expr = build2 (GT_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SGE:
|
||||
case BRIG_COMPARE_GE:
|
||||
expr = build2 (GE_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SEQU:
|
||||
case BRIG_COMPARE_EQU:
|
||||
expr = build2 (UNEQ_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SNEU:
|
||||
case BRIG_COMPARE_NEU:
|
||||
expr = build2 (NE_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SLTU:
|
||||
case BRIG_COMPARE_LTU:
|
||||
expr = build2 (UNLT_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SLEU:
|
||||
case BRIG_COMPARE_LEU:
|
||||
expr = build2 (UNLE_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SGTU:
|
||||
case BRIG_COMPARE_GTU:
|
||||
expr = build2 (UNGT_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SGEU:
|
||||
case BRIG_COMPARE_GEU:
|
||||
expr = build2 (UNGE_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SNUM:
|
||||
case BRIG_COMPARE_NUM:
|
||||
expr = build2 (ORDERED_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
case BRIG_COMPARE_SNAN:
|
||||
case BRIG_COMPARE_NAN:
|
||||
expr = build2 (UNORDERED_EXPR, result_type, operands[1], operands[2]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (expr == NULL_TREE)
|
||||
gcc_unreachable ();
|
||||
|
||||
if (is_fp16_dest)
|
||||
{
|
||||
expr = convert_to_real (brig_to_generic::s_fp32_type, expr);
|
||||
}
|
||||
else if (VECTOR_TYPE_P (dest_type) && ANY_INTEGRAL_TYPE_P (dest_type)
|
||||
&& !is_boolean_dest
|
||||
&& (inst->sourceType & BRIG_TYPE_BASE_MASK) != BRIG_TYPE_F16)
|
||||
{
|
||||
/* In later gcc versions, the output of comparison is not
|
||||
all ones for vectors like still in 4.9.1. We need to use
|
||||
an additional VEC_COND_EXPR to produce the all ones 'true' value
|
||||
required by HSA.
|
||||
VEC_COND_EXPR <a == b, { -1, -1, -1, -1 }, { 0, 0, 0, 0 }>; */
|
||||
|
||||
tree all_ones
|
||||
= build_vector_from_val (dest_type,
|
||||
build_minus_one_cst (TREE_TYPE (dest_type)));
|
||||
tree all_zeroes
|
||||
= build_vector_from_val (dest_type,
|
||||
build_zero_cst (TREE_TYPE (dest_type)));
|
||||
expr = build3 (VEC_COND_EXPR, dest_type, expr, all_ones, all_zeroes);
|
||||
}
|
||||
else if (INTEGRAL_TYPE_P (dest_type) && !is_boolean_dest)
|
||||
{
|
||||
/* We need to produce the all-ones pattern for the width of the whole
|
||||
resulting integer type. Use back and forth shifts for propagating
|
||||
the lower 1. */
|
||||
tree signed_type = signed_type_for (dest_type);
|
||||
tree signed_result = convert_to_integer (signed_type, expr);
|
||||
|
||||
size_t result_width = int_size_in_bytes (dest_type) * BITS_PER_UNIT;
|
||||
|
||||
tree shift_amount_cst
|
||||
= build_int_cstu (signed_type, result_width - 1);
|
||||
|
||||
tree shift_left_result
|
||||
= build2 (LSHIFT_EXPR, signed_type, signed_result, shift_amount_cst);
|
||||
|
||||
expr = build2 (RSHIFT_EXPR, signed_type, shift_left_result,
|
||||
shift_amount_cst);
|
||||
}
|
||||
else if (SCALAR_FLOAT_TYPE_P (dest_type))
|
||||
{
|
||||
expr = convert_to_real (dest_type, expr);
|
||||
}
|
||||
else if (VECTOR_TYPE_P (dest_type)
|
||||
&& (inst->sourceType & BRIG_TYPE_BASE_MASK) == BRIG_TYPE_F16)
|
||||
{
|
||||
/* Because F16 comparison is emulated as an F32 comparison with S32
|
||||
results, we must now truncate the result vector to S16s so it
|
||||
fits to the destination register. We can build the target vector
|
||||
type from the f16 storage type (unsigned ints). */
|
||||
expr = add_temp_var ("wide_cmp_result", expr);
|
||||
tree_stl_vec wide_elements;
|
||||
tree_stl_vec shrunk_elements;
|
||||
unpack (expr, wide_elements);
|
||||
for (size_t i = 0; i < wide_elements.size (); ++i)
|
||||
{
|
||||
tree wide = wide_elements.at (i);
|
||||
shrunk_elements.push_back
|
||||
(convert_to_integer (short_integer_type_node, wide));
|
||||
}
|
||||
expr = pack (shrunk_elements);
|
||||
}
|
||||
build_output_assignment (*inst_base, operands[0], expr);
|
||||
|
||||
return base->byteCount;
|
||||
}
|
1716
gcc/brig/brigfrontend/brig-code-entry-handler.cc
Normal file
1716
gcc/brig/brigfrontend/brig-code-entry-handler.cc
Normal file
File diff suppressed because it is too large
Load diff
425
gcc/brig/brigfrontend/brig-code-entry-handler.h
Normal file
425
gcc/brig/brigfrontend/brig-code-entry-handler.h
Normal file
|
@ -0,0 +1,425 @@
|
|||
/* brig-code-entry-handler.h -- a gccbrig base class
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_BRIG_CODE_ENTRY_HANDLER_H
|
||||
#define GCC_BRIG_CODE_ENTRY_HANDLER_H
|
||||
|
||||
#include "brig-to-generic.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
class tree_element_unary_visitor;
|
||||
|
||||
/* An interface to organize the different types of element handlers
|
||||
for the code section. */
|
||||
|
||||
class brig_code_entry_handler : public brig_entry_handler
|
||||
{
|
||||
public:
|
||||
typedef std::map<std::pair<BrigOpcode16_t, BrigType16_t>, tree> builtin_map;
|
||||
|
||||
brig_code_entry_handler (brig_to_generic &parent);
|
||||
|
||||
/* Handles the brig_code data at the given pointer and adds it to the
|
||||
currently built tree. Returns the number of consumed bytes. */
|
||||
|
||||
virtual size_t operator () (const BrigBase *base) = 0;
|
||||
|
||||
void append_statement (tree stmt);
|
||||
|
||||
protected:
|
||||
|
||||
tree get_tree_expr_type_for_hsa_type (BrigType16_t brig_type) const;
|
||||
tree get_tree_cst_for_hsa_operand (const BrigOperandConstantBytes *brigConst,
|
||||
tree type) const;
|
||||
tree get_builtin_for_hsa_opcode (tree type, BrigOpcode16_t brig_opcode,
|
||||
BrigType16_t brig_type) const;
|
||||
tree get_comparison_result_type (tree source_type);
|
||||
|
||||
tree build_code_ref (const BrigBase &ref);
|
||||
|
||||
tree build_tree_operand (const BrigInstBase &brig_inst,
|
||||
const BrigBase &operand,
|
||||
tree operand_type = NULL_TREE,
|
||||
bool is_input = false);
|
||||
|
||||
tree build_address_operand (const BrigInstBase &brig_inst,
|
||||
const BrigOperandAddress &addr_operand);
|
||||
|
||||
tree build_tree_operand_from_brig (const BrigInstBase *brig_inst,
|
||||
tree operand_type, size_t operand_index);
|
||||
|
||||
tree build_tree_cst_element (BrigType16_t element_type,
|
||||
const unsigned char *next_data) const;
|
||||
|
||||
bool needs_workitem_context_data (BrigOpcode16_t brig_opcode) const;
|
||||
|
||||
void unpack (tree value, tree_stl_vec &elements);
|
||||
tree pack (tree_stl_vec &elements);
|
||||
|
||||
bool can_expand_builtin (BrigOpcode16_t brig_opcode) const;
|
||||
tree expand_builtin (BrigOpcode16_t brig_opcode, tree_stl_vec &operands);
|
||||
|
||||
tree expand_or_call_builtin (BrigOpcode16_t brig_opcode,
|
||||
BrigType16_t brig_type, tree arith_type,
|
||||
tree_stl_vec &operands);
|
||||
|
||||
tree add_temp_var (std::string name, tree expr);
|
||||
|
||||
tree build_f2h_conversion (tree source);
|
||||
tree build_h2f_conversion (tree source);
|
||||
|
||||
tree_stl_vec build_operands (const BrigInstBase &brig_inst);
|
||||
tree build_output_assignment (const BrigInstBase &brig_inst, tree output,
|
||||
tree inst_expr);
|
||||
|
||||
tree apply_to_all_elements (tree_element_unary_visitor &visitor,
|
||||
tree operand);
|
||||
|
||||
HOST_WIDE_INT int_constant_value (tree node);
|
||||
|
||||
tree extend_int (tree input, tree dest_type, tree src_type);
|
||||
|
||||
/* HSAIL-specific builtin functions not yet integrated to gcc. */
|
||||
|
||||
static builtin_map s_custom_builtins;
|
||||
};
|
||||
|
||||
/* Implement the Visitor software pattern for performing various actions on
|
||||
elements of vector operands. This enables separating the vector element
|
||||
traversal/extraction/packing code from whatever different actions are
|
||||
performed to each element. */
|
||||
|
||||
class tree_element_unary_visitor
|
||||
{
|
||||
public:
|
||||
tree operator () (brig_code_entry_handler &handler, tree operand);
|
||||
|
||||
/* Performs an action to a single element, which can have originally
|
||||
been a vector element or a scalar. */
|
||||
|
||||
virtual tree visit_element (brig_code_entry_handler &handler, tree operand)
|
||||
= 0;
|
||||
};
|
||||
|
||||
class tree_element_binary_visitor
|
||||
{
|
||||
public:
|
||||
tree operator () (brig_code_entry_handler &handler, tree operand0,
|
||||
tree operand1);
|
||||
|
||||
/* Performs an action to a pair of elements, which can have originally
|
||||
been a vector element or a scalar. */
|
||||
|
||||
virtual tree visit_element (brig_code_entry_handler &handler, tree operand0,
|
||||
tree operand1)
|
||||
= 0;
|
||||
};
|
||||
|
||||
/* Visitor for flushing float elements to zero. */
|
||||
|
||||
class flush_to_zero : public tree_element_unary_visitor
|
||||
{
|
||||
public:
|
||||
flush_to_zero (bool fp16) : m_fp16 (fp16)
|
||||
{
|
||||
}
|
||||
|
||||
virtual tree visit_element (brig_code_entry_handler &caller, tree operand);
|
||||
|
||||
private:
|
||||
|
||||
/* True if the value should be flushed according to fp16 limits. */
|
||||
|
||||
bool m_fp16;
|
||||
};
|
||||
|
||||
/* Visitor for converting F16 elements to F32. */
|
||||
|
||||
class half_to_float : public tree_element_unary_visitor
|
||||
{
|
||||
public:
|
||||
virtual tree visit_element (brig_code_entry_handler &caller, tree operand);
|
||||
};
|
||||
|
||||
/* Visitor for converting F32 elements to F16. */
|
||||
|
||||
class float_to_half : public tree_element_unary_visitor
|
||||
{
|
||||
public:
|
||||
virtual tree visit_element (brig_code_entry_handler &caller, tree operand);
|
||||
};
|
||||
|
||||
/* A base class for instruction types that support floating point
|
||||
modifiers.
|
||||
|
||||
operator () delegates to subclasses (template method pattern) in
|
||||
type specific parts. */
|
||||
|
||||
class brig_inst_mod_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_inst_mod_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
virtual size_t generate (const BrigBase *base);
|
||||
virtual const BrigAluModifier8_t *modifier (const BrigBase *base) const;
|
||||
virtual const BrigRound8_t *round (const BrigBase *base) const;
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_directive_function_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_directive_function_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_directive_control_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_directive_control_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_directive_variable_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_directive_variable_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
|
||||
tree build_variable (const BrigDirectiveVariable *brigVar,
|
||||
tree_code var_decltype = VAR_DECL);
|
||||
|
||||
size_t get_brig_var_alignment (const BrigDirectiveVariable *brigVar);
|
||||
};
|
||||
|
||||
class brig_directive_fbarrier_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_directive_fbarrier_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_directive_label_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_directive_label_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_directive_comment_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_directive_comment_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_directive_arg_block_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_directive_arg_block_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_basic_inst_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_basic_inst_handler (brig_to_generic &parent);
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
|
||||
private:
|
||||
tree build_lower_element_broadcast (tree vec_operand);
|
||||
|
||||
bool must_be_scalarized (const BrigInstBase *brig_inst,
|
||||
tree instr_type) const;
|
||||
|
||||
tree build_inst_expr (BrigOpcode16_t brig_opcode, BrigType16_t brig_type,
|
||||
tree arith_type, tree_stl_vec &operands);
|
||||
|
||||
tree build_shuffle (tree arith_type, tree_stl_vec &operands);
|
||||
tree build_unpack (tree_stl_vec &operands);
|
||||
tree build_pack (tree_stl_vec &operands);
|
||||
|
||||
tree build_unpack_lo_or_hi (BrigOpcode16_t brig_opcode, tree arith_type,
|
||||
tree_stl_vec &operands);
|
||||
|
||||
tree_code get_tree_code_for_hsa_opcode (BrigOpcode16_t brig_opcode,
|
||||
BrigType16_t brig_type) const;
|
||||
};
|
||||
|
||||
class brig_cvt_inst_handler : public brig_inst_mod_handler
|
||||
{
|
||||
public:
|
||||
brig_cvt_inst_handler (brig_to_generic &parent)
|
||||
: brig_inst_mod_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
virtual size_t generate (const BrigBase *base);
|
||||
virtual const BrigAluModifier8_t *modifier (const BrigBase *base) const;
|
||||
virtual const BrigRound8_t *round (const BrigBase *base) const;
|
||||
};
|
||||
|
||||
class brig_branch_inst_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_branch_inst_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_mem_inst_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_mem_inst_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
|
||||
private:
|
||||
tree build_mem_access (const BrigInstBase *brig_inst, tree addr, tree data);
|
||||
};
|
||||
|
||||
class brig_copy_move_inst_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_copy_move_inst_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
|
||||
private:
|
||||
size_t handle_lda (const BrigInstBase *base);
|
||||
};
|
||||
|
||||
class brig_atomic_inst_handler : public brig_code_entry_handler
|
||||
{
|
||||
private:
|
||||
typedef std::map<std::string, tree> atomic_builtins_map;
|
||||
|
||||
public:
|
||||
brig_atomic_inst_handler (brig_to_generic &parent);
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
|
||||
protected:
|
||||
size_t generate_tree (const BrigInstBase &inst,
|
||||
BrigAtomicOperation8_t atomic_opcode);
|
||||
};
|
||||
|
||||
class brig_signal_inst_handler : public brig_atomic_inst_handler
|
||||
{
|
||||
public:
|
||||
brig_signal_inst_handler (brig_to_generic &parent)
|
||||
: brig_atomic_inst_handler (parent)
|
||||
{
|
||||
}
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_cmp_inst_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_cmp_inst_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_seg_inst_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_seg_inst_handler (brig_to_generic &parent);
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_lane_inst_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_lane_inst_handler (brig_to_generic &parent);
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_queue_inst_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_queue_inst_handler (brig_to_generic &parent);
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
class brig_directive_module_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_directive_module_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t operator () (const BrigBase *base);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
38
gcc/brig/brigfrontend/brig-comment-handler.cc
Normal file
38
gcc/brig/brigfrontend/brig-comment-handler.cc
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* brig-comment-handler.cc -- brig comment directive handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
|
||||
extern int gccbrig_verbose;
|
||||
|
||||
size_t
|
||||
brig_directive_comment_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigDirectiveComment *brig_comment
|
||||
= (const BrigDirectiveComment *) base;
|
||||
|
||||
if (gccbrig_verbose)
|
||||
{
|
||||
std::string cmnt = m_parent.get_string (brig_comment->name);
|
||||
fprintf (stderr, "brig: Comment: '%s'\n", cmnt.c_str());
|
||||
}
|
||||
return base->byteCount;
|
||||
}
|
108
gcc/brig/brigfrontend/brig-control-handler.cc
Normal file
108
gcc/brig/brigfrontend/brig-control-handler.cc
Normal file
|
@ -0,0 +1,108 @@
|
|||
/* brig-control-handler.cc -- brig control directive handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "diagnostic.h"
|
||||
#include "print-tree.h"
|
||||
|
||||
size_t
|
||||
brig_directive_control_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigDirectiveControl *inst = (const BrigDirectiveControl *) base;
|
||||
const BrigData *operand_entries
|
||||
= m_parent.get_brig_data_entry (inst->operands);
|
||||
|
||||
/* Parse the constant integer operands. */
|
||||
std::vector<tree> operands;
|
||||
for (size_t i = 0; i < operand_entries->byteCount / 4; ++i)
|
||||
{
|
||||
uint32_t operand_offset
|
||||
= ((const uint32_t *) &operand_entries->bytes)[i];
|
||||
const BrigBase *operand_data
|
||||
= m_parent.get_brig_operand_entry (operand_offset);
|
||||
|
||||
tree operand_type
|
||||
= (inst->control == BRIG_CONTROL_REQUIREDGRIDSIZE
|
||||
|| inst->control == BRIG_CONTROL_MAXFLATGRIDSIZE) ?
|
||||
uint64_type_node : uint32_type_node;
|
||||
operands.push_back
|
||||
(build_tree_operand (*(const BrigInstBase*)inst, *operand_data,
|
||||
operand_type));
|
||||
}
|
||||
|
||||
switch (inst->control)
|
||||
{
|
||||
case BRIG_CONTROL_MAXDYNAMICGROUPSIZE:
|
||||
{
|
||||
m_parent.m_cf->m_descriptor.max_dynamic_group_size
|
||||
= int_constant_value (operands.at (0));
|
||||
break;
|
||||
}
|
||||
case BRIG_CONTROL_MAXFLATGRIDSIZE:
|
||||
{
|
||||
m_parent.m_cf->m_descriptor.max_flat_grid_size
|
||||
= int_constant_value (operands.at (0));
|
||||
break;
|
||||
}
|
||||
case BRIG_CONTROL_MAXFLATWORKGROUPSIZE:
|
||||
{
|
||||
m_parent.m_cf->m_descriptor.max_flat_workgroup_size
|
||||
= int_constant_value (operands.at (0));
|
||||
break;
|
||||
}
|
||||
case BRIG_CONTROL_REQUIREDDIM:
|
||||
{
|
||||
m_parent.m_cf->m_descriptor.required_dim
|
||||
= int_constant_value (operands.at (0));
|
||||
break;
|
||||
}
|
||||
case BRIG_CONTROL_REQUIREDGRIDSIZE:
|
||||
{
|
||||
m_parent.m_cf->m_descriptor.required_grid_size[0]
|
||||
= int_constant_value (operands.at (0));
|
||||
m_parent.m_cf->m_descriptor.required_grid_size[1]
|
||||
= int_constant_value (operands.at (1));
|
||||
m_parent.m_cf->m_descriptor.required_grid_size[2]
|
||||
= int_constant_value (operands.at (2));
|
||||
break;
|
||||
}
|
||||
case BRIG_CONTROL_REQUIREDWORKGROUPSIZE:
|
||||
{
|
||||
m_parent.m_cf->m_descriptor.required_workgroup_size[0]
|
||||
= int_constant_value (operands.at (0));
|
||||
m_parent.m_cf->m_descriptor.required_workgroup_size[1]
|
||||
= int_constant_value (operands.at (1));
|
||||
m_parent.m_cf->m_descriptor.required_workgroup_size[2]
|
||||
= int_constant_value (operands.at (2));
|
||||
break;
|
||||
}
|
||||
case BRIG_CONTROL_REQUIRENOPARTIALWORKGROUPS:
|
||||
/* Performance hint only, ignored for now. */
|
||||
break;
|
||||
case BRIG_CONTROL_ENABLEBREAKEXCEPTIONS:
|
||||
case BRIG_CONTROL_ENABLEDETECTEXCEPTIONS:
|
||||
/* Unimplemented. */
|
||||
break;
|
||||
default:
|
||||
sorry ("Unsupported control directive %x.\n", inst->control);
|
||||
}
|
||||
return base->byteCount;
|
||||
}
|
73
gcc/brig/brigfrontend/brig-copy-move-inst-handler.cc
Normal file
73
gcc/brig/brigfrontend/brig-copy-move-inst-handler.cc
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* brig-copy-move-inst-handler.cc -- brig copy/move instruction handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "print-tree.h"
|
||||
#include "errors.h"
|
||||
#include "brig-util.h"
|
||||
|
||||
size_t
|
||||
brig_copy_move_inst_handler::handle_lda (const BrigInstBase *brig_inst)
|
||||
{
|
||||
tree dest_type = gccbrig_tree_type_for_hsa_type (brig_inst->type);
|
||||
|
||||
tree input = build_tree_operand_from_brig (brig_inst, NULL, 1);
|
||||
tree output = build_tree_operand_from_brig (brig_inst, dest_type, 0);
|
||||
|
||||
build_output_assignment (*brig_inst, output, input);
|
||||
return brig_inst->base.byteCount;
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_copy_move_inst_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigInstBase *brig_inst
|
||||
= (const BrigInstBase *) &((const BrigInstBasic *) base)->base;
|
||||
|
||||
if (brig_inst->opcode == BRIG_OPCODE_LDA)
|
||||
return handle_lda (brig_inst);
|
||||
|
||||
const BrigInstSourceType *inst_src_type = (const BrigInstSourceType *) base;
|
||||
|
||||
tree source_type = gccbrig_tree_type_for_hsa_type (inst_src_type->sourceType);
|
||||
tree dest_type = gccbrig_tree_type_for_hsa_type (brig_inst->type);
|
||||
|
||||
tree input = build_tree_operand_from_brig (brig_inst, source_type, 1);
|
||||
tree output = build_tree_operand_from_brig (brig_inst, dest_type, 0);
|
||||
if (brig_inst->opcode == BRIG_OPCODE_COMBINE)
|
||||
{
|
||||
/* For combine, a simple reinterpret cast from the array constructor
|
||||
works. */
|
||||
|
||||
tree casted = build_reinterpret_cast (dest_type, input);
|
||||
tree assign = build2 (MODIFY_EXPR, TREE_TYPE (output), output, casted);
|
||||
m_parent.m_cf->append_statement (assign);
|
||||
}
|
||||
else if (brig_inst->opcode == BRIG_OPCODE_EXPAND)
|
||||
build_output_assignment (*brig_inst, output, input);
|
||||
else
|
||||
{
|
||||
brig_basic_inst_handler basic (m_parent);
|
||||
return basic (base);
|
||||
}
|
||||
return base->byteCount;
|
||||
}
|
260
gcc/brig/brigfrontend/brig-cvt-inst-handler.cc
Normal file
260
gcc/brig/brigfrontend/brig-cvt-inst-handler.cc
Normal file
|
@ -0,0 +1,260 @@
|
|||
/* brig-cvt-inst-handler.cc -- brig cvt (convert) instruction handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
|
||||
#include "gimple-expr.h"
|
||||
#include "errors.h"
|
||||
#include "convert.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "print-tree.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "brig-util.h"
|
||||
|
||||
const BrigAluModifier8_t *
|
||||
brig_cvt_inst_handler::modifier (const BrigBase *base) const
|
||||
{
|
||||
const BrigInstCvt *inst = (const BrigInstCvt *) base;
|
||||
return &inst->modifier;
|
||||
}
|
||||
|
||||
const BrigRound8_t *
|
||||
brig_cvt_inst_handler::round (const BrigBase *base) const
|
||||
{
|
||||
const BrigInstCvt *inst = (const BrigInstCvt *) base;
|
||||
return &inst->round;
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_cvt_inst_handler::generate (const BrigBase *base)
|
||||
{
|
||||
/* In cvt instructions there can be at least four data types involved:
|
||||
|
||||
- the input register type
|
||||
- the output register type
|
||||
- the conversion source type
|
||||
- the conversion destination type
|
||||
*/
|
||||
|
||||
const BrigInstBase *brig_inst
|
||||
= (const BrigInstBase *) &((const BrigInstBasic *) base)->base;
|
||||
const BrigInstCvt *cvt_inst = (const BrigInstCvt *) base;
|
||||
|
||||
const BrigAluModifier8_t *inst_modifier = modifier (base);
|
||||
const bool FTZ = inst_modifier != NULL && (*inst_modifier) & BRIG_ALU_FTZ;
|
||||
|
||||
/* The conversion source type. */
|
||||
tree src_type = get_tree_expr_type_for_hsa_type (cvt_inst->sourceType);
|
||||
|
||||
bool src_is_fp16 = cvt_inst->sourceType == BRIG_TYPE_F16;
|
||||
|
||||
/* The conversion destination type. */
|
||||
tree dest_type = gccbrig_tree_type_for_hsa_type (brig_inst->type);
|
||||
|
||||
bool dest_is_fp16 = brig_inst->type == BRIG_TYPE_F16;
|
||||
|
||||
if (!dest_type || !src_type)
|
||||
{
|
||||
gcc_unreachable ();
|
||||
return base->byteCount;
|
||||
}
|
||||
|
||||
tree_stl_vec operands = build_operands (*brig_inst);
|
||||
tree &input = operands.at (1);
|
||||
tree &output = operands.at (0);
|
||||
|
||||
size_t conv_src_size = int_size_in_bytes (src_type);
|
||||
size_t conv_dst_size = int_size_in_bytes (dest_type);
|
||||
size_t src_reg_size = int_size_in_bytes (TREE_TYPE (input));
|
||||
|
||||
/* The input register can be of different type&size than the
|
||||
conversion input size. First cast the input to the conversion
|
||||
input type. These casts are always bitcasts which can be
|
||||
expressed as casts between different unsigned integers. */
|
||||
if (src_reg_size != conv_src_size)
|
||||
{
|
||||
tree unsigned_int_type = NULL_TREE;
|
||||
if (INTEGRAL_TYPE_P (src_type))
|
||||
unsigned_int_type = unsigned_type_for (src_type);
|
||||
else /* Find a matching size int type for the REAL type. */
|
||||
{
|
||||
if (conv_src_size == 2)
|
||||
unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U16);
|
||||
else if (conv_src_size == 4)
|
||||
unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U32);
|
||||
else if (conv_src_size == 8)
|
||||
unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U64);
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
input = convert_to_integer (unsigned_int_type, input);
|
||||
}
|
||||
|
||||
if (src_is_fp16)
|
||||
input = build_h2f_conversion (input);
|
||||
|
||||
/* Flush the float operand to zero if indicated with 'ftz'. */
|
||||
if (FTZ && SCALAR_FLOAT_TYPE_P (src_type))
|
||||
{
|
||||
tree casted_input = build_reinterpret_cast (src_type, input);
|
||||
input = flush_to_zero (src_is_fp16) (*this, casted_input);
|
||||
}
|
||||
|
||||
tree conversion_result = NULL_TREE;
|
||||
if (brig_inst->type == BRIG_TYPE_B1)
|
||||
{
|
||||
/* When the destination is b1, cvt does a 'ztest' operation which is
|
||||
defined as a != 0 for integers and similarly (!= 0.0f) for floats. */
|
||||
if (INTEGRAL_TYPE_P (src_type))
|
||||
{
|
||||
/* Generate an integer not equal operation. */
|
||||
conversion_result = build2 (NE_EXPR, TREE_TYPE (input), input,
|
||||
build_int_cst (TREE_TYPE (input), 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For REAL source types, ztest returns 1 if the value is not +- 0.0f.
|
||||
We can perform this check with an integer comparison after
|
||||
masking away the sign bit from a correct position. This is safer
|
||||
than using absf because of exceptions in case of a NaN
|
||||
input (NaN exceptions are not generated with cvt). */
|
||||
tree unsigned_int_type = NULL_TREE;
|
||||
/* Bit battern with all but the upper bit 1. */
|
||||
tree and_mask = NULL_TREE;
|
||||
if (conv_src_size == 2)
|
||||
{
|
||||
unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U16);
|
||||
and_mask = build_int_cst (unsigned_int_type, 0x7FFF);
|
||||
}
|
||||
else if (conv_src_size == 4)
|
||||
{
|
||||
unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U32);
|
||||
and_mask = build_int_cst (unsigned_int_type, 0x7FFFFFFF);
|
||||
}
|
||||
else if (conv_src_size == 8)
|
||||
{
|
||||
unsigned_int_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U64);
|
||||
and_mask = build_int_cst (unsigned_int_type, 0x7FFFFFFFFFFFFFFF);
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
tree casted_input = build_reinterpret_cast (unsigned_int_type, input);
|
||||
tree masked_input
|
||||
= build2 (BIT_AND_EXPR, unsigned_int_type, casted_input, and_mask);
|
||||
conversion_result
|
||||
= build2 (NE_EXPR, TREE_TYPE (masked_input), masked_input,
|
||||
build_int_cst (unsigned_int_type, 0));
|
||||
}
|
||||
/* The result from the comparison is a boolean, convert it to such. */
|
||||
conversion_result
|
||||
= convert_to_integer (gccbrig_tree_type_for_hsa_type (BRIG_TYPE_B1),
|
||||
conversion_result);
|
||||
}
|
||||
else if (dest_is_fp16)
|
||||
{
|
||||
tree casted_input = build_reinterpret_cast (src_type, input);
|
||||
conversion_result
|
||||
= convert_to_real (brig_to_generic::s_fp32_type, casted_input);
|
||||
if (FTZ)
|
||||
conversion_result = flush_to_zero (true) (*this, conversion_result);
|
||||
conversion_result = build_f2h_conversion (conversion_result);
|
||||
}
|
||||
else if (SCALAR_FLOAT_TYPE_P (dest_type))
|
||||
{
|
||||
tree casted_input = build_reinterpret_cast (src_type, input);
|
||||
conversion_result = convert_to_real (dest_type, casted_input);
|
||||
}
|
||||
else if (INTEGRAL_TYPE_P (dest_type) && INTEGRAL_TYPE_P (src_type))
|
||||
{
|
||||
conversion_result = extend_int (input, dest_type, src_type);
|
||||
}
|
||||
else if (INTEGRAL_TYPE_P (dest_type) && SCALAR_FLOAT_TYPE_P (src_type))
|
||||
{
|
||||
|
||||
if (cvt_inst->round == BRIG_ROUND_INTEGER_ZERO_SAT)
|
||||
{
|
||||
|
||||
/* Use builtins for the saturating conversions. */
|
||||
#undef DEF_HSAIL_SAT_BUILTIN
|
||||
#undef DEF_HSAIL_BUILTIN
|
||||
#undef DEF_HSAIL_ATOMIC_BUILTIN
|
||||
#undef DEF_HSAIL_INTR_BUILTIN
|
||||
#undef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN
|
||||
|
||||
tree builtin = NULL_TREE;
|
||||
BrigType16_t src_arith_type
|
||||
= src_is_fp16
|
||||
? (BrigType16_t) BRIG_TYPE_F32 : cvt_inst->sourceType;
|
||||
#define DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN(ENUM, HSAIL_DST_TYPE, HSAIL_SRC_TYPE, \
|
||||
NAME, TYPE, ATTRS) \
|
||||
if (brig_inst->type == HSAIL_DST_TYPE \
|
||||
&& src_arith_type == HSAIL_SRC_TYPE) \
|
||||
builtin = builtin_decl_explicit (ENUM); \
|
||||
else
|
||||
#include "brig-builtins.def"
|
||||
gcc_unreachable ();
|
||||
|
||||
tree casted_input = build_reinterpret_cast (src_type, input);
|
||||
conversion_result
|
||||
= call_builtin (builtin, 1, dest_type, src_type, casted_input);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree casted_input = build_reinterpret_cast (src_type, input);
|
||||
|
||||
/* Perform the int to float conversion. */
|
||||
conversion_result = convert_to_integer (dest_type, casted_input);
|
||||
}
|
||||
/* The converted result is finally extended to the target register
|
||||
width, using the same sign as the destination. */
|
||||
conversion_result
|
||||
= convert_to_integer (TREE_TYPE (output), conversion_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just use CONVERT_EXPR and hope for the best. */
|
||||
tree casted_input = build_reinterpret_cast (dest_type, input);
|
||||
conversion_result = build1 (CONVERT_EXPR, dest_type, casted_input);
|
||||
}
|
||||
|
||||
size_t dst_reg_size = int_size_in_bytes (TREE_TYPE (output));
|
||||
|
||||
tree assign = NULL_TREE;
|
||||
/* The output register can be of different type&size than the
|
||||
conversion output size. Cast it to the register variable type. */
|
||||
if (dst_reg_size > conv_dst_size)
|
||||
{
|
||||
tree casted_output
|
||||
= build1 (CONVERT_EXPR, TREE_TYPE (output), conversion_result);
|
||||
assign = build2 (MODIFY_EXPR, TREE_TYPE (output), output, casted_output);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree casted_output
|
||||
= build_reinterpret_cast (TREE_TYPE (output), conversion_result);
|
||||
assign = build2 (MODIFY_EXPR, TREE_TYPE (output), output, casted_output);
|
||||
}
|
||||
m_parent.m_cf->append_statement (assign);
|
||||
|
||||
return base->byteCount;
|
||||
}
|
44
gcc/brig/brigfrontend/brig-fbarrier-handler.cc
Normal file
44
gcc/brig/brigfrontend/brig-fbarrier-handler.cc
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* brig-fbarrier-handler.cc -- brig fbarrier directive handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
|
||||
#include "stringpool.h"
|
||||
#include "errors.h"
|
||||
|
||||
/* Allocate this many bytes from the group segment for each fbarrier. */
|
||||
#define FBARRIER_STRUCT_SIZE 32
|
||||
|
||||
size_t
|
||||
brig_directive_fbarrier_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
/* Model fbarriers as group segment variables with fixed size
|
||||
large enough to store whatever data the actual target needs
|
||||
to store to maintain the barrier info. The handle is the
|
||||
offset to the beginning of the object. */
|
||||
|
||||
const BrigDirectiveFbarrier* fbar = (const BrigDirectiveFbarrier*)base;
|
||||
if (m_parent.m_cf != NULL)
|
||||
m_parent.m_cf->m_function_scope_vars.insert (base);
|
||||
std::string var_name = m_parent.get_mangled_name (fbar);
|
||||
m_parent.append_group_variable (var_name, FBARRIER_STRUCT_SIZE, 1);
|
||||
return base->byteCount;
|
||||
}
|
374
gcc/brig/brigfrontend/brig-function-handler.cc
Normal file
374
gcc/brig/brigfrontend/brig-function-handler.cc
Normal file
|
@ -0,0 +1,374 @@
|
|||
/* brig-code-entry-handler.cc -- brig function directive handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
|
||||
#include "brig-machine.h"
|
||||
#include "stringpool.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "gimple-expr.h"
|
||||
#include "function.h"
|
||||
#include "phsa.h"
|
||||
|
||||
#include "tree-pretty-print.h"
|
||||
#include "print-tree.h"
|
||||
|
||||
extern int gccbrig_verbose;
|
||||
|
||||
size_t
|
||||
brig_directive_function_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
m_parent.finish_function ();
|
||||
|
||||
size_t bytes_consumed = base->byteCount;
|
||||
|
||||
const BrigDirectiveExecutable *exec = (const BrigDirectiveExecutable *) base;
|
||||
|
||||
if (gccbrig_verbose)
|
||||
{
|
||||
printf ("brig: function name %s\n",
|
||||
m_parent.get_string (exec->name).c_str());
|
||||
printf ("brig: inargs %d outargs %d name offset %d\n", exec->inArgCount,
|
||||
exec->outArgCount, exec->name);
|
||||
}
|
||||
|
||||
const bool is_definition
|
||||
= exec->modifier & BRIG_EXECUTABLE_DEFINITION;
|
||||
|
||||
const bool is_kernel = base->kind == BRIG_KIND_DIRECTIVE_KERNEL;
|
||||
|
||||
/* There doesn't seem to be actual use cases for kernel declarations
|
||||
as they cannot be called by the program. Ignore them until there's
|
||||
a reason not to. */
|
||||
if (is_kernel && !is_definition)
|
||||
return bytes_consumed;
|
||||
|
||||
m_parent.m_cf = new brig_function (exec, &m_parent);
|
||||
|
||||
std::string func_name = m_parent.get_mangled_name (exec);
|
||||
|
||||
tree fndecl;
|
||||
tree ret_value = NULL_TREE;
|
||||
|
||||
tree stmt_list = alloc_stmt_list ();
|
||||
|
||||
/* Add a function scope BIND_EXPR using which we can push local variables that
|
||||
represent HSAIL registers. */
|
||||
tree bind_expr = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL);
|
||||
|
||||
if (is_kernel)
|
||||
{
|
||||
/* The generated kernel function is not the one that should be
|
||||
called by the host. */
|
||||
func_name = std::string ("_") + func_name;
|
||||
|
||||
tree name_identifier
|
||||
= get_identifier_with_length (func_name.c_str (), func_name.size ());
|
||||
|
||||
/* The generated kernel functions take the following arguments:
|
||||
|
||||
1) a char* which is a starting address of the argument segment where
|
||||
the call's arguments are stored by the launcher.
|
||||
2) a void* parameter that points to a phsail-finalizer context object
|
||||
which passes the hsa kernel packet etc.
|
||||
3) a void* parameter that contains the first flat address of the group
|
||||
region allocated to the current work-group. */
|
||||
|
||||
tree char_ptr_type_node = build_pointer_type (char_type_node);
|
||||
fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier,
|
||||
build_function_type_list (void_type_node,
|
||||
char_ptr_type_node,
|
||||
ptr_type_node,
|
||||
ptr_type_node, NULL_TREE));
|
||||
|
||||
SET_DECL_ASSEMBLER_NAME (fndecl, name_identifier);
|
||||
|
||||
tree resdecl
|
||||
= build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, void_type_node);
|
||||
|
||||
tree typelist = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
|
||||
tree argtype = TREE_VALUE (typelist);
|
||||
TYPE_ADDR_SPACE (argtype)
|
||||
= gccbrig_get_target_addr_space_id (BRIG_SEGMENT_KERNARG);
|
||||
|
||||
tree arg_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL,
|
||||
get_identifier ("__args"), char_ptr_type_node);
|
||||
DECL_ARGUMENTS (fndecl) = arg_arg;
|
||||
DECL_ARG_TYPE (arg_arg) = char_ptr_type_node;
|
||||
DECL_CONTEXT (arg_arg) = fndecl;
|
||||
DECL_ARTIFICIAL (arg_arg) = 1;
|
||||
TREE_READONLY (arg_arg) = 1;
|
||||
TREE_USED (arg_arg) = 1;
|
||||
|
||||
DECL_RESULT (fndecl) = resdecl;
|
||||
DECL_CONTEXT (resdecl) = fndecl;
|
||||
DECL_EXTERNAL (fndecl) = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Build a regular function fingerprint to enable targets to optimize
|
||||
the calling convention as they see fit. */
|
||||
tree name_identifier
|
||||
= get_identifier_with_length (func_name.c_str (), func_name.size ());
|
||||
|
||||
m_parent.m_cf->m_arg_variables.clear ();
|
||||
|
||||
brig_directive_variable_handler arg_handler (m_parent);
|
||||
|
||||
vec<tree, va_gc> *args;
|
||||
vec_alloc (args, 4);
|
||||
|
||||
tree arg_decls = NULL_TREE;
|
||||
|
||||
tree ret_type = void_type_node;
|
||||
if (exec->outArgCount == 1)
|
||||
{
|
||||
/* The return value variable should be the first entry after the
|
||||
function directive. */
|
||||
const BrigBase *retval
|
||||
= (const BrigBase *) ((const char *) base + base->byteCount);
|
||||
gcc_assert (retval->kind == BRIG_KIND_DIRECTIVE_VARIABLE);
|
||||
|
||||
const BrigDirectiveVariable *brigVar
|
||||
= (const BrigDirectiveVariable *) retval;
|
||||
|
||||
brig_directive_variable_handler varhandler (m_parent);
|
||||
|
||||
if (brigVar->type & BRIG_TYPE_ARRAY)
|
||||
{
|
||||
/* Push array output arguments to the beginning of the
|
||||
function argument list instead of regular function
|
||||
return values. */
|
||||
|
||||
tree arg_var = varhandler.build_variable (brigVar, PARM_DECL);
|
||||
vec_safe_push (args, TREE_TYPE (arg_var));
|
||||
|
||||
m_parent.m_cf->add_arg_variable (brigVar, arg_var);
|
||||
|
||||
if (arg_decls == NULL_TREE)
|
||||
arg_decls = arg_var;
|
||||
else
|
||||
chainon (arg_decls, arg_var);
|
||||
|
||||
m_parent.m_cf->add_arg_variable (brigVar, arg_var);
|
||||
|
||||
ret_value = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
|
||||
void_type_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = varhandler.build_variable (brigVar, RESULT_DECL);
|
||||
m_parent.m_cf->m_ret_value = ret_value;
|
||||
ret_type = TREE_TYPE (ret_value);
|
||||
m_parent.m_cf->m_ret_value_brig_var = brigVar;
|
||||
}
|
||||
bytes_consumed += retval->byteCount;
|
||||
}
|
||||
else
|
||||
ret_value = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
|
||||
void_type_node);
|
||||
|
||||
TREE_ADDRESSABLE (ret_value) = 1;
|
||||
|
||||
if (exec->inArgCount > 0)
|
||||
{
|
||||
uint32_t arg_offset = exec->firstInArg;
|
||||
for (size_t arg = 0; arg < exec->inArgCount; ++arg)
|
||||
{
|
||||
|
||||
const BrigDirectiveVariable *brigVar
|
||||
= (const BrigDirectiveVariable *) m_parent.get_brig_code_entry
|
||||
(arg_offset);
|
||||
|
||||
gcc_assert (brigVar->base.kind == BRIG_KIND_DIRECTIVE_VARIABLE);
|
||||
|
||||
/* Delegate to the brig_directive_variable_handler. */
|
||||
brig_directive_variable_handler varhandler (m_parent);
|
||||
tree arg_var = varhandler.build_variable (brigVar, PARM_DECL);
|
||||
arg_offset += brigVar->base.byteCount;
|
||||
vec_safe_push (args, TREE_TYPE (arg_var));
|
||||
|
||||
m_parent.m_cf->add_arg_variable (brigVar, arg_var);
|
||||
|
||||
if (arg_decls == NULL_TREE)
|
||||
arg_decls = arg_var;
|
||||
else
|
||||
chainon (arg_decls, arg_var);
|
||||
}
|
||||
}
|
||||
|
||||
vec_safe_push (args, ptr_type_node);
|
||||
vec_safe_push (args, ptr_type_node);
|
||||
|
||||
fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier,
|
||||
build_function_type_vec (ret_type, args));
|
||||
|
||||
DECL_RESULT (fndecl) = ret_value;
|
||||
DECL_CONTEXT (ret_value) = fndecl;
|
||||
DECL_EXTERNAL (fndecl) = 0;
|
||||
DECL_ARGUMENTS (fndecl) = arg_decls;
|
||||
}
|
||||
|
||||
/* All functions need the hidden __context argument passed on
|
||||
because they might call WI-specific functions which need
|
||||
the context info. */
|
||||
tree context_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL,
|
||||
get_identifier ("__context"), ptr_type_node);
|
||||
if (DECL_ARGUMENTS (fndecl) == NULL_TREE)
|
||||
DECL_ARGUMENTS (fndecl) = context_arg;
|
||||
else
|
||||
chainon (DECL_ARGUMENTS (fndecl), context_arg);
|
||||
DECL_CONTEXT (context_arg) = fndecl;
|
||||
DECL_ARG_TYPE (context_arg) = ptr_type_node;
|
||||
DECL_ARTIFICIAL (context_arg) = 1;
|
||||
TREE_READONLY (context_arg) = 1;
|
||||
TREE_USED (context_arg) = 1;
|
||||
|
||||
/* They can also access group memory, so we need to pass the
|
||||
group pointer along too. */
|
||||
tree group_base_arg
|
||||
= build_decl (UNKNOWN_LOCATION, PARM_DECL,
|
||||
get_identifier ("__group_base_addr"), ptr_type_node);
|
||||
chainon (DECL_ARGUMENTS (fndecl), group_base_arg);
|
||||
DECL_ARG_TYPE (group_base_arg) = ptr_type_node;
|
||||
DECL_CONTEXT (group_base_arg) = fndecl;
|
||||
DECL_ARTIFICIAL (group_base_arg) = 1;
|
||||
TREE_READONLY (group_base_arg) = 1;
|
||||
TREE_USED (group_base_arg) = 1;
|
||||
|
||||
/* Same for private. */
|
||||
tree private_base_arg
|
||||
= build_decl (UNKNOWN_LOCATION, PARM_DECL,
|
||||
get_identifier ("__private_base_addr"), ptr_type_node);
|
||||
chainon (DECL_ARGUMENTS (fndecl), private_base_arg);
|
||||
DECL_ARG_TYPE (private_base_arg) = ptr_type_node;
|
||||
DECL_CONTEXT (private_base_arg) = fndecl;
|
||||
DECL_ARTIFICIAL (private_base_arg) = 1;
|
||||
TREE_READONLY (private_base_arg) = 1;
|
||||
TREE_USED (private_base_arg) = 1;
|
||||
|
||||
DECL_SAVED_TREE (fndecl) = bind_expr;
|
||||
|
||||
/* Try to preserve the functions across IPA. */
|
||||
DECL_PRESERVE_P (fndecl) = 1;
|
||||
TREE_SIDE_EFFECTS (fndecl) = 1;
|
||||
|
||||
TREE_ADDRESSABLE (fndecl) = 1;
|
||||
|
||||
if (base->kind == BRIG_KIND_DIRECTIVE_FUNCTION)
|
||||
{
|
||||
TREE_STATIC (fndecl) = 1;
|
||||
TREE_PUBLIC (fndecl) = 1;
|
||||
}
|
||||
else if (base->kind == BRIG_KIND_DIRECTIVE_KERNEL)
|
||||
{
|
||||
TREE_STATIC (fndecl) = 1;
|
||||
TREE_PUBLIC (fndecl) = 1;
|
||||
}
|
||||
else if (base->kind == BRIG_KIND_DIRECTIVE_SIGNATURE)
|
||||
{
|
||||
TREE_STATIC (fndecl) = 0;
|
||||
TREE_PUBLIC (fndecl) = 1;
|
||||
DECL_EXTERNAL (fndecl) = 1;
|
||||
}
|
||||
else if (base->kind == BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION)
|
||||
{
|
||||
TREE_STATIC (fndecl) = 0;
|
||||
TREE_PUBLIC (fndecl) = 1;
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
TREE_USED (fndecl) = 1;
|
||||
DECL_ARTIFICIAL (fndecl) = 0;
|
||||
|
||||
tree initial_block = make_node (BLOCK);
|
||||
DECL_INITIAL (fndecl) = initial_block;
|
||||
TREE_USED (DECL_INITIAL (fndecl)) = 1;
|
||||
|
||||
if (ret_value != NULL_TREE && TREE_TYPE (ret_value) != void_type_node)
|
||||
{
|
||||
DECL_CONTEXT (ret_value) = fndecl;
|
||||
DECL_CHAIN (ret_value) = BIND_EXPR_VARS (bind_expr);
|
||||
BIND_EXPR_VARS (bind_expr) = ret_value;
|
||||
}
|
||||
|
||||
tree arg;
|
||||
for (arg = DECL_ARGUMENTS (fndecl); arg != NULL_TREE; arg = TREE_CHAIN (arg))
|
||||
{
|
||||
DECL_CONTEXT (arg) = fndecl;
|
||||
DECL_ARG_TYPE (arg) = TREE_TYPE (arg);
|
||||
}
|
||||
|
||||
m_parent.add_function_decl (func_name, fndecl);
|
||||
m_parent.append_global (fndecl);
|
||||
|
||||
if (!is_definition)
|
||||
return bytes_consumed;
|
||||
|
||||
m_parent.start_function (fndecl);
|
||||
|
||||
m_parent.m_cf->m_name = func_name;
|
||||
m_parent.m_cf->m_func_decl = fndecl;
|
||||
m_parent.m_cf->m_current_bind_expr = bind_expr;
|
||||
m_parent.m_cf->m_is_kernel = is_kernel;
|
||||
m_parent.m_cf->m_context_arg = context_arg;
|
||||
m_parent.m_cf->m_group_base_arg = group_base_arg;
|
||||
m_parent.m_cf->m_private_base_arg = private_base_arg;
|
||||
|
||||
if (ret_value != NULL_TREE && TREE_TYPE (ret_value) != void_type_node)
|
||||
{
|
||||
/* We cannot assign to <<retval>> directly in gcc trunk. We need to
|
||||
create a local temporary variable which can be stored to and when
|
||||
returning from the function, we'll copy it to the actual <<retval>>
|
||||
in return statement's argument. */
|
||||
tree temp_var = m_parent.m_cf->m_ret_temp
|
||||
= m_parent.m_cf->add_local_variable ("_retvalue_temp",
|
||||
TREE_TYPE (ret_value));
|
||||
TREE_ADDRESSABLE (temp_var) = 1;
|
||||
}
|
||||
|
||||
if (is_kernel)
|
||||
{
|
||||
m_parent.m_cf->add_id_variables ();
|
||||
|
||||
/* Create a single entry point in the function. */
|
||||
m_parent.m_cf->m_entry_label_stmt
|
||||
= build_stmt (LABEL_EXPR, m_parent.m_cf->label ("__kernel_entry"));
|
||||
m_parent.m_cf->append_statement (m_parent.m_cf->m_entry_label_stmt);
|
||||
|
||||
tree bind_expr = m_parent.m_cf->m_current_bind_expr;
|
||||
tree stmts = BIND_EXPR_BODY (bind_expr);
|
||||
|
||||
m_parent.m_cf->m_kernel_entry = tsi_last (stmts);
|
||||
|
||||
/* Let's not append the exit label yet, but only after the
|
||||
function has been built. We need to build it so it can
|
||||
be referred to because returns are converted to gotos to this
|
||||
label. */
|
||||
m_parent.m_cf->m_exit_label = m_parent.m_cf->label ("__kernel_exit");
|
||||
}
|
||||
|
||||
return bytes_consumed;
|
||||
}
|
723
gcc/brig/brigfrontend/brig-function.cc
Normal file
723
gcc/brig/brigfrontend/brig-function.cc
Normal file
|
@ -0,0 +1,723 @@
|
|||
/* brig-function.cc -- declaration of brig_function class.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "brig-function.h"
|
||||
#include "stringpool.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "toplev.h"
|
||||
#include "gimplify.h"
|
||||
#include "gimple-expr.h"
|
||||
#include "print-tree.h"
|
||||
#include "hsa-brig-format.h"
|
||||
#include "stor-layout.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "brig-machine.h"
|
||||
#include "brig-util.h"
|
||||
#include "phsa.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "dumpfile.h"
|
||||
#include "tree-cfg.h"
|
||||
#include "errors.h"
|
||||
#include "function.h"
|
||||
#include "brig-to-generic.h"
|
||||
#include "brig-builtins.h"
|
||||
|
||||
brig_function::brig_function (const BrigDirectiveExecutable *exec,
|
||||
brig_to_generic *parent)
|
||||
: m_brig_def (exec), m_is_kernel (false), m_is_finished (false), m_name (""),
|
||||
m_current_bind_expr (NULL_TREE), m_func_decl (NULL_TREE),
|
||||
m_context_arg (NULL_TREE), m_group_base_arg (NULL_TREE),
|
||||
m_private_base_arg (NULL_TREE), m_ret_value (NULL_TREE),
|
||||
m_next_kernarg_offset (0), m_kernarg_max_align (0),
|
||||
m_ret_value_brig_var (NULL), m_has_barriers (false),
|
||||
m_has_allocas (false), m_has_function_calls_with_barriers (false),
|
||||
m_calls_analyzed (false), m_is_wg_function (false),
|
||||
m_has_unexpanded_dp_builtins (false), m_generating_arg_block (false),
|
||||
m_parent (parent)
|
||||
{
|
||||
memset (m_regs, 0,
|
||||
BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT * sizeof (BrigOperandRegister *));
|
||||
memset (&m_descriptor, 0, sizeof (phsa_descriptor));
|
||||
}
|
||||
|
||||
brig_function::~brig_function ()
|
||||
{
|
||||
for (size_t i = 0; i < BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT; ++i)
|
||||
{
|
||||
if (m_regs[i] != NULL)
|
||||
{
|
||||
delete m_regs[i];
|
||||
m_regs[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns a GENERIC label with the given name in the given function.
|
||||
Creates it, if not yet found. */
|
||||
|
||||
tree
|
||||
brig_function::label (const std::string &name)
|
||||
{
|
||||
label_index::const_iterator i = m_label_index.find (name);
|
||||
if (i == m_label_index.end ())
|
||||
{
|
||||
tree name_identifier
|
||||
= get_identifier_with_length (name.c_str (), name.size ());
|
||||
|
||||
tree label_decl = build_decl (UNKNOWN_LOCATION, LABEL_DECL,
|
||||
name_identifier, void_type_node);
|
||||
|
||||
DECL_CONTEXT (label_decl) = m_func_decl;
|
||||
DECL_ARTIFICIAL (label_decl) = 0;
|
||||
|
||||
m_label_index[name] = label_decl;
|
||||
return label_decl;
|
||||
}
|
||||
else
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
/* Record an argument variable for later use. This includes both local
|
||||
variables inside arg blocks and incoming function arguments. */
|
||||
|
||||
void
|
||||
brig_function::add_arg_variable (const BrigDirectiveVariable *brigVar,
|
||||
tree treeDecl)
|
||||
{
|
||||
m_arg_variables[brigVar] = treeDecl;
|
||||
}
|
||||
|
||||
tree
|
||||
brig_function::arg_variable (const BrigDirectiveVariable *var) const
|
||||
{
|
||||
variable_index::const_iterator i = m_arg_variables.find (var);
|
||||
if (i == m_arg_variables.end ())
|
||||
return NULL_TREE;
|
||||
else
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
/* Appends a new kernel argument descriptor for the current kernel's
|
||||
arg space. */
|
||||
|
||||
void
|
||||
brig_function::append_kernel_arg (const BrigDirectiveVariable *var, size_t size,
|
||||
size_t alignment)
|
||||
{
|
||||
gcc_assert (m_func_decl != NULL_TREE);
|
||||
gcc_assert (m_is_kernel);
|
||||
|
||||
size_t align_padding = m_next_kernarg_offset % alignment == 0 ?
|
||||
0 : (alignment - m_next_kernarg_offset % alignment);
|
||||
m_next_kernarg_offset += align_padding;
|
||||
m_kernarg_offsets[var] = m_next_kernarg_offset;
|
||||
m_next_kernarg_offset += size;
|
||||
|
||||
m_kernarg_max_align
|
||||
= m_kernarg_max_align < alignment ? alignment : m_kernarg_max_align;
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_function::kernel_arg_offset (const BrigDirectiveVariable *var) const
|
||||
{
|
||||
var_offset_table::const_iterator i = m_kernarg_offsets.find (var);
|
||||
gcc_assert (i != m_kernarg_offsets.end ());
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
/* Add work-item ID variables to the beginning of the kernel function
|
||||
which can be used for address computation as kernel dispatch packet
|
||||
instructions can be expanded to GENERIC nodes referring to them. */
|
||||
|
||||
void
|
||||
brig_function::add_id_variables ()
|
||||
{
|
||||
tree bind_expr = m_current_bind_expr;
|
||||
tree stmts = BIND_EXPR_BODY (bind_expr);
|
||||
|
||||
/* Initialize the WG limits and local ids. */
|
||||
|
||||
tree_stmt_iterator entry = tsi_start (stmts);
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
char dim_char = (char) ((int) 'x' + i);
|
||||
|
||||
/* The local sizes are limited to 16b values, but let's still use 32b
|
||||
to avoid unnecessary casts (the ID functions are 32b). */
|
||||
m_local_id_vars[i]
|
||||
= add_local_variable (std::string ("__local_") + dim_char,
|
||||
uint32_type_node);
|
||||
|
||||
tree workitemid_call
|
||||
= call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_WORKITEMID), 2,
|
||||
uint32_type_node, uint32_type_node,
|
||||
build_int_cst (uint32_type_node, i), ptr_type_node,
|
||||
m_context_arg);
|
||||
|
||||
tree id_init = build2 (MODIFY_EXPR, TREE_TYPE (m_local_id_vars[i]),
|
||||
m_local_id_vars[i], workitemid_call);
|
||||
|
||||
tsi_link_after (&entry, id_init, TSI_NEW_STMT);
|
||||
|
||||
m_cur_wg_size_vars[i]
|
||||
= add_local_variable (std::string ("__cur_wg_size_") + dim_char,
|
||||
uint32_type_node);
|
||||
|
||||
tree cwgz_call
|
||||
= call_builtin
|
||||
(builtin_decl_explicit (BUILT_IN_HSAIL_CURRENTWORKGROUPSIZE),
|
||||
2, uint32_type_node, uint32_type_node,
|
||||
build_int_cst (uint32_type_node, i), ptr_type_node, m_context_arg);
|
||||
|
||||
tree limit_init = build2 (MODIFY_EXPR, TREE_TYPE (m_cur_wg_size_vars[i]),
|
||||
m_cur_wg_size_vars[i], cwgz_call);
|
||||
|
||||
tsi_link_after (&entry, limit_init, TSI_NEW_STMT);
|
||||
|
||||
m_wg_id_vars[i]
|
||||
= add_local_variable (std::string ("__workgroupid_") + dim_char,
|
||||
uint32_type_node);
|
||||
|
||||
tree wgid_call
|
||||
= call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_WORKGROUPID),
|
||||
2, uint32_type_node, uint32_type_node,
|
||||
build_int_cst (uint32_type_node, i), ptr_type_node,
|
||||
m_context_arg);
|
||||
|
||||
tree wgid_init = build2 (MODIFY_EXPR, TREE_TYPE (m_wg_id_vars[i]),
|
||||
m_wg_id_vars[i], wgid_call);
|
||||
|
||||
tsi_link_after (&entry, wgid_init, TSI_NEW_STMT);
|
||||
|
||||
m_wg_size_vars[i]
|
||||
= add_local_variable (std::string ("__workgroupsize_") + dim_char,
|
||||
uint32_type_node);
|
||||
|
||||
tree wgsize_call
|
||||
= call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_WORKGROUPSIZE),
|
||||
2, uint32_type_node, uint32_type_node,
|
||||
build_int_cst (uint32_type_node, i), ptr_type_node,
|
||||
m_context_arg);
|
||||
|
||||
tree wgsize_init = build2 (MODIFY_EXPR, TREE_TYPE (m_wg_size_vars[i]),
|
||||
m_wg_size_vars[i], wgsize_call);
|
||||
|
||||
tsi_link_after (&entry, wgsize_init, TSI_NEW_STMT);
|
||||
|
||||
m_grid_size_vars[i]
|
||||
= add_local_variable (std::string ("__gridsize_") + dim_char,
|
||||
uint32_type_node);
|
||||
|
||||
tree gridsize_call
|
||||
= call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_GRIDSIZE), 2,
|
||||
uint32_type_node, uint32_type_node,
|
||||
build_int_cst (uint32_type_node, i), ptr_type_node,
|
||||
m_context_arg);
|
||||
|
||||
tree gridsize_init = build2 (MODIFY_EXPR, TREE_TYPE (m_grid_size_vars[i]),
|
||||
m_grid_size_vars[i], gridsize_call);
|
||||
|
||||
tsi_link_after (&entry, gridsize_init, TSI_NEW_STMT);
|
||||
}
|
||||
|
||||
m_kernel_entry = entry;
|
||||
}
|
||||
|
||||
/* Creates a new local variable with the given NAME and given GENERIC
|
||||
TYPE. */
|
||||
|
||||
tree
|
||||
brig_function::add_local_variable (std::string name, tree type)
|
||||
{
|
||||
tree name_identifier
|
||||
= get_identifier_with_length (name.c_str (), name.size ());
|
||||
tree variable
|
||||
= build_decl (UNKNOWN_LOCATION, VAR_DECL, name_identifier, type);
|
||||
|
||||
DECL_NONLOCAL (variable) = 0;
|
||||
TREE_ADDRESSABLE (variable) = 0;
|
||||
TREE_STATIC (variable) = 0;
|
||||
TREE_USED (variable) = 1;
|
||||
DECL_ARTIFICIAL (variable) = 0;
|
||||
|
||||
tree bind_expr = DECL_SAVED_TREE (m_func_decl);
|
||||
|
||||
DECL_CONTEXT (variable) = m_func_decl;
|
||||
|
||||
DECL_CHAIN (variable) = BIND_EXPR_VARS (bind_expr);
|
||||
BIND_EXPR_VARS (bind_expr) = variable;
|
||||
return variable;
|
||||
}
|
||||
|
||||
/* Returns a DECL_VAR for the given HSAIL operand register.
|
||||
If it has not been created yet for the function being generated,
|
||||
creates it as an unsigned int variable. */
|
||||
|
||||
tree
|
||||
brig_function::get_m_var_declfor_reg (const BrigOperandRegister *reg)
|
||||
{
|
||||
size_t offset = reg->regNum;
|
||||
switch (reg->regKind)
|
||||
{
|
||||
case BRIG_REGISTER_KIND_QUAD:
|
||||
offset
|
||||
+= BRIG_2_TREE_HSAIL_D_REG_COUNT + BRIG_2_TREE_HSAIL_S_REG_COUNT +
|
||||
BRIG_2_TREE_HSAIL_C_REG_COUNT;
|
||||
break;
|
||||
case BRIG_REGISTER_KIND_DOUBLE:
|
||||
offset += BRIG_2_TREE_HSAIL_S_REG_COUNT + BRIG_2_TREE_HSAIL_C_REG_COUNT;
|
||||
break;
|
||||
case BRIG_REGISTER_KIND_SINGLE:
|
||||
offset += BRIG_2_TREE_HSAIL_C_REG_COUNT;
|
||||
case BRIG_REGISTER_KIND_CONTROL:
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
}
|
||||
|
||||
reg_decl_index_entry *regEntry = m_regs[offset];
|
||||
if (regEntry == NULL)
|
||||
{
|
||||
size_t reg_size = gccbrig_reg_size (reg);
|
||||
tree type;
|
||||
if (reg_size > 1)
|
||||
type = build_nonstandard_integer_type (reg_size, true);
|
||||
else
|
||||
type = boolean_type_node;
|
||||
|
||||
/* Drop the const qualifier so we do not end up with a read only
|
||||
register variable which cannot be written to later. */
|
||||
tree nonconst_type = build_type_variant (type, false, false);
|
||||
|
||||
regEntry = new reg_decl_index_entry;
|
||||
|
||||
regEntry->m_var_decl
|
||||
= add_local_variable (gccbrig_reg_name (reg), nonconst_type);
|
||||
m_regs[offset] = regEntry;
|
||||
}
|
||||
return regEntry->m_var_decl;
|
||||
}
|
||||
|
||||
/* Builds a work-item do..while loop for a single DIM. HEADER_ENTRY is
|
||||
a statement after which the iteration variables should be initialized and
|
||||
the loop body starts. BRANCH_AFTER is the statement after which the loop
|
||||
predicate check and the back edge goto will be appended. */
|
||||
|
||||
void
|
||||
brig_function::add_wi_loop (int dim, tree_stmt_iterator *header_entry,
|
||||
tree_stmt_iterator *branch_after)
|
||||
{
|
||||
tree ivar = m_local_id_vars[dim];
|
||||
tree ivar_max = m_cur_wg_size_vars[dim];
|
||||
tree_stmt_iterator entry = *header_entry;
|
||||
|
||||
/* TODO: this is not a parallel loop as we share the "register variables"
|
||||
across work-items. Should create a copy of them per WI instance. That
|
||||
is, declare temporaries for new definitions inside the loop body, not at
|
||||
function scope. */
|
||||
|
||||
tree ivar_init = build2 (MODIFY_EXPR, TREE_TYPE (ivar), ivar,
|
||||
build_zero_cst (TREE_TYPE (ivar)));
|
||||
tsi_link_after (&entry, ivar_init, TSI_NEW_STMT);
|
||||
|
||||
tree loop_body_label
|
||||
= label (std::string ("__wi_loop_") + (char) ((int) 'x' + dim));
|
||||
tree loop_body_label_stmt = build_stmt (LABEL_EXPR, loop_body_label);
|
||||
|
||||
tsi_link_after (&entry, loop_body_label_stmt, TSI_NEW_STMT);
|
||||
|
||||
if (m_has_unexpanded_dp_builtins)
|
||||
{
|
||||
tree id_set_builtin
|
||||
= builtin_decl_explicit (BUILT_IN_HSAIL_SETWORKITEMID);
|
||||
/* Set the local ID to the current wi-loop iteration variable value to
|
||||
ensure the builtins see the correct values. */
|
||||
tree id_set_call
|
||||
= call_builtin (id_set_builtin, 3,
|
||||
void_type_node, uint32_type_node,
|
||||
build_int_cst (uint32_type_node, dim), uint32_type_node,
|
||||
ivar, ptr_type_node, m_context_arg);
|
||||
tsi_link_after (&entry, id_set_call, TSI_NEW_STMT);
|
||||
}
|
||||
|
||||
/* Increment the WI iteration variable. */
|
||||
tree incr = build2 (PREINCREMENT_EXPR, TREE_TYPE (ivar), ivar,
|
||||
build_one_cst (TREE_TYPE (ivar)));
|
||||
|
||||
tsi_link_after (branch_after, incr, TSI_NEW_STMT);
|
||||
|
||||
/* Append the predicate check with the back edge goto. */
|
||||
tree condition = build2 (LT_EXPR, TREE_TYPE (ivar), ivar, ivar_max);
|
||||
tree target_goto = build1 (GOTO_EXPR, void_type_node, loop_body_label);
|
||||
tree if_stmt
|
||||
= build3 (COND_EXPR, void_type_node, condition, target_goto, NULL_TREE);
|
||||
tsi_link_after (branch_after, if_stmt, TSI_NEW_STMT);
|
||||
}
|
||||
|
||||
/* Recursively analyzes the function and its callees for barrier usage. */
|
||||
|
||||
void
|
||||
brig_function::analyze_calls ()
|
||||
{
|
||||
if (m_calls_analyzed)
|
||||
return;
|
||||
|
||||
/* Set this early to not get stuck in case of recursive call graphs.
|
||||
This is safe because if the function calls itself, either the function
|
||||
has barrier calls which implies a call to a function with barrier calls,
|
||||
or it doesn't in which case the result depends on the later called
|
||||
functions. */
|
||||
m_calls_analyzed = true;
|
||||
|
||||
for (size_t i = 0; i < m_called_functions.size (); ++i)
|
||||
{
|
||||
tree f = m_called_functions[i];
|
||||
brig_function *called_f = m_parent->get_finished_function (f);
|
||||
if (called_f == NULL)
|
||||
{
|
||||
/* Unfinished function (only declaration within the set of BRIGs)
|
||||
found. Cannot finish the CG analysis. Have to assume it does have
|
||||
a barrier for safety. */
|
||||
m_has_function_calls_with_barriers = true;
|
||||
m_has_unexpanded_dp_builtins = true;
|
||||
break;
|
||||
}
|
||||
called_f->analyze_calls ();
|
||||
/* We can assume m_has_barriers has been correctly set during the
|
||||
construction of the function decl. No need to reanalyze it. */
|
||||
m_has_function_calls_with_barriers |= called_f->m_has_barriers;
|
||||
|
||||
/* If the function or any of its called functions has dispatch
|
||||
packet builtin calls that require the local id, we need to
|
||||
set the local id to the context in the work item loop before
|
||||
the functions are called. If we analyze the opposite, these
|
||||
function calls can be omitted. */
|
||||
m_has_unexpanded_dp_builtins |= called_f->m_has_unexpanded_dp_builtins;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tries to convert the current kernel to a work-group function that executes
|
||||
all work-items using loops. Returns true in case the conversion was
|
||||
successful. */
|
||||
|
||||
bool
|
||||
brig_function::convert_to_wg_function ()
|
||||
{
|
||||
if (!m_calls_analyzed)
|
||||
analyze_calls ();
|
||||
|
||||
if (m_has_barriers || m_has_function_calls_with_barriers)
|
||||
return false;
|
||||
|
||||
/* The most trivial case: No barriers at all in the kernel.
|
||||
We can create one big work-item loop around the whole kernel. */
|
||||
tree bind_expr = m_current_bind_expr;
|
||||
tree stmts = BIND_EXPR_BODY (bind_expr);
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
/* The previous loop has added a new label to the end of the function,
|
||||
the next level loop should wrap around it also. */
|
||||
tree_stmt_iterator function_exit = tsi_last (stmts);
|
||||
add_wi_loop (i, &m_kernel_entry, &function_exit);
|
||||
}
|
||||
|
||||
m_is_wg_function = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Emits a kernel description to a special ELF section so it can be
|
||||
utilized by an HSA runtime implementation. The assembly block
|
||||
must be emitted to a statement list of an function, which is given
|
||||
as an argument. Returns the assembly block used to emit the section. */
|
||||
|
||||
tree
|
||||
brig_function::emit_metadata (tree stmt_list)
|
||||
{
|
||||
/* Emit an ELF section via an assembly directive that generates a special
|
||||
ELF section for each kernel that contains raw bytes of a descriptor
|
||||
object. This is pretty disgusting, but life is never perfect ;) */
|
||||
|
||||
/* Use the original kernel name without the '_' prefix in the section name. */
|
||||
std::string kern_name = m_is_kernel ? m_name.substr (1) : m_name;
|
||||
|
||||
std::ostringstream strstr;
|
||||
strstr << std::endl
|
||||
<< ".pushsection " << PHSA_DESC_SECTION_PREFIX << kern_name
|
||||
<< std::endl
|
||||
<< "\t.p2align 1, 1, 1" << std::endl
|
||||
<< "\t.byte ";
|
||||
|
||||
for (size_t i = 0; i < sizeof (phsa_descriptor); ++i)
|
||||
{
|
||||
strstr << "0x" << std::setw (2) << std::setfill ('0') << std::hex
|
||||
<< (unsigned) *((unsigned char *) &m_descriptor + i);
|
||||
if (i + 1 < sizeof (phsa_descriptor))
|
||||
strstr << ", ";
|
||||
}
|
||||
|
||||
strstr << std::endl << ".popsection" << std::endl << std::endl;
|
||||
|
||||
tree metadata_asm
|
||||
= build_stmt (ASM_EXPR,
|
||||
build_string (strstr.str ().size (), strstr.str ().c_str ()),
|
||||
NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
|
||||
append_to_statement_list_force (metadata_asm, &stmt_list);
|
||||
return metadata_asm;
|
||||
}
|
||||
|
||||
/* Emits the kernel launcher function. Also emits the metadata section
|
||||
creation statements in it.
|
||||
|
||||
The launcher function calls the device-side runtime
|
||||
that runs the kernel for all work-items. In C:
|
||||
|
||||
void KernelName (void* context, void* group_base_addr)
|
||||
{
|
||||
__hsail_launch_kernel (_KernelName, context, group_base_addr);
|
||||
}
|
||||
|
||||
or, in case of a successful conversion to a work-group function:
|
||||
|
||||
void KernelName (void* context, void* group_base_addr)
|
||||
{
|
||||
__hsail_launch_wg_function (_KernelName, context, group_base_addr);
|
||||
}
|
||||
|
||||
The user/host sees this function as the kernel to call from the
|
||||
outside. The actual kernel generated from HSAIL was named _KernelName.
|
||||
*/
|
||||
|
||||
tree
|
||||
brig_function::emit_launcher_and_metadata ()
|
||||
{
|
||||
/* The original kernel name without the '_' prefix. */
|
||||
std::string kern_name = m_name.substr (1);
|
||||
|
||||
tree name_identifier
|
||||
= get_identifier_with_length (kern_name.c_str (), kern_name.size ());
|
||||
|
||||
tree launcher
|
||||
= build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, name_identifier,
|
||||
build_function_type_list (void_type_node, ptr_type_node,
|
||||
ptr_type_node, NULL_TREE));
|
||||
|
||||
TREE_USED (launcher) = 1;
|
||||
DECL_ARTIFICIAL (launcher) = 1;
|
||||
|
||||
tree context_arg = build_decl (UNKNOWN_LOCATION, PARM_DECL,
|
||||
get_identifier ("__context"), ptr_type_node);
|
||||
|
||||
DECL_ARGUMENTS (launcher) = context_arg;
|
||||
DECL_ARG_TYPE (context_arg) = ptr_type_node;
|
||||
DECL_CONTEXT (context_arg) = launcher;
|
||||
TREE_USED (context_arg) = 1;
|
||||
DECL_ARTIFICIAL (context_arg) = 1;
|
||||
|
||||
tree group_base_addr_arg
|
||||
= build_decl (UNKNOWN_LOCATION, PARM_DECL,
|
||||
get_identifier ("__group_base_addr"), ptr_type_node);
|
||||
|
||||
chainon (DECL_ARGUMENTS (launcher), group_base_addr_arg);
|
||||
DECL_ARG_TYPE (group_base_addr_arg) = ptr_type_node;
|
||||
DECL_CONTEXT (group_base_addr_arg) = launcher;
|
||||
TREE_USED (group_base_addr_arg) = 1;
|
||||
DECL_ARTIFICIAL (group_base_addr_arg) = 1;
|
||||
|
||||
tree resdecl
|
||||
= build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, void_type_node);
|
||||
|
||||
DECL_RESULT (launcher) = resdecl;
|
||||
DECL_CONTEXT (resdecl) = launcher;
|
||||
|
||||
DECL_INITIAL (launcher) = make_node (BLOCK);
|
||||
TREE_USED (DECL_INITIAL (launcher)) = 1;
|
||||
|
||||
tree stmt_list = alloc_stmt_list ();
|
||||
|
||||
tree bind_expr = build3 (BIND_EXPR, void_type_node, NULL, stmt_list, NULL);
|
||||
|
||||
TREE_STATIC (launcher) = 0;
|
||||
TREE_PUBLIC (launcher) = 1;
|
||||
|
||||
DECL_SAVED_TREE (launcher) = bind_expr;
|
||||
|
||||
if (DECL_STRUCT_FUNCTION (launcher) == NULL)
|
||||
push_struct_function (launcher);
|
||||
else
|
||||
push_cfun (DECL_STRUCT_FUNCTION (launcher));
|
||||
|
||||
tree kernel_func_ptr = build1 (ADDR_EXPR, ptr_type_node, m_func_decl);
|
||||
|
||||
tree phsail_launch_kernel_call;
|
||||
|
||||
/* Emit a launcher depending whether we converted the kernel function to
|
||||
a work group function or not. */
|
||||
if (m_is_wg_function)
|
||||
phsail_launch_kernel_call
|
||||
= call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_LAUNCH_WG_FUNC),
|
||||
3, void_type_node,
|
||||
ptr_type_node, kernel_func_ptr, ptr_type_node,
|
||||
context_arg, ptr_type_node, group_base_addr_arg);
|
||||
else
|
||||
phsail_launch_kernel_call
|
||||
= call_builtin (builtin_decl_explicit (BUILT_IN_HSAIL_LAUNCH_KERNEL),
|
||||
3, void_type_node,
|
||||
ptr_type_node, kernel_func_ptr, ptr_type_node,
|
||||
context_arg, ptr_type_node, group_base_addr_arg);
|
||||
|
||||
append_to_statement_list_force (phsail_launch_kernel_call, &stmt_list);
|
||||
|
||||
emit_metadata (stmt_list);
|
||||
|
||||
return launcher;
|
||||
}
|
||||
|
||||
tree
|
||||
brig_function::append_statement (tree stmt)
|
||||
{
|
||||
gcc_assert (m_func_decl != NULL);
|
||||
|
||||
tree bind_expr = m_current_bind_expr;
|
||||
tree stmts = BIND_EXPR_BODY (bind_expr);
|
||||
|
||||
append_to_statement_list_force (stmt, &stmts);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
/* Creates a new "alloca frame" for the current function by
|
||||
injecting an alloca frame push in the beginning of the function
|
||||
and an alloca frame pop before all function exit points. */
|
||||
|
||||
void
|
||||
brig_function::create_alloca_frame ()
|
||||
{
|
||||
tree_stmt_iterator entry;
|
||||
|
||||
/* Adds the alloca push only after the ids have been initialized
|
||||
in case of a kernel function. */
|
||||
if (m_is_kernel)
|
||||
entry = m_kernel_entry;
|
||||
else
|
||||
{
|
||||
tree bind_expr = m_current_bind_expr;
|
||||
tree stmts = BIND_EXPR_BODY (bind_expr);
|
||||
entry = tsi_start (stmts);
|
||||
}
|
||||
|
||||
tree push_frame_builtin = builtin_decl_explicit (BUILT_IN_HSAIL_PUSH_FRAME);
|
||||
tree push_frame_call
|
||||
= call_builtin (push_frame_builtin, 1, void_type_node, ptr_type_node,
|
||||
m_context_arg);
|
||||
|
||||
tsi_link_before (&entry, push_frame_call, TSI_NEW_STMT);
|
||||
|
||||
tree pop_frame_builtin = builtin_decl_explicit (BUILT_IN_HSAIL_POP_FRAME);
|
||||
|
||||
do
|
||||
{
|
||||
tree stmt = tsi_stmt (entry);
|
||||
if (TREE_CODE (stmt) == RETURN_EXPR)
|
||||
{
|
||||
tree pop_frame_call
|
||||
= call_builtin (pop_frame_builtin, 1, void_type_node,
|
||||
ptr_type_node, m_context_arg);
|
||||
|
||||
tsi_link_before (&entry, pop_frame_call, TSI_SAME_STMT);
|
||||
}
|
||||
tsi_next (&entry);
|
||||
}
|
||||
while (!tsi_end_p (entry));
|
||||
}
|
||||
|
||||
/* Finishes the currently built function. After calling this, no new
|
||||
statements should be appeneded to the function. */
|
||||
void
|
||||
brig_function::finish ()
|
||||
{
|
||||
append_return_stmt ();
|
||||
|
||||
/* Currently assume single alloca frame per WG. */
|
||||
if (m_has_allocas)
|
||||
create_alloca_frame ();
|
||||
}
|
||||
|
||||
void
|
||||
brig_function::finish_kernel ()
|
||||
{
|
||||
/* Kernel functions should have a single exit point.
|
||||
Let's create one. The return instructions should have
|
||||
been converted to branches to this label. */
|
||||
append_statement (build_stmt (LABEL_EXPR, m_exit_label));
|
||||
/* Attempt to convert the kernel to a work-group function that
|
||||
executes all work-items of the WG using a loop. */
|
||||
convert_to_wg_function ();
|
||||
|
||||
append_return_stmt ();
|
||||
|
||||
/* Currently assume single alloca frame per WG. */
|
||||
if (m_has_allocas)
|
||||
create_alloca_frame ();
|
||||
}
|
||||
|
||||
void
|
||||
brig_function::append_return_stmt ()
|
||||
{
|
||||
gcc_assert (m_current_bind_expr != NULL_TREE);
|
||||
tree stmts = BIND_EXPR_BODY (m_current_bind_expr);
|
||||
|
||||
if (STATEMENT_LIST_TAIL (stmts) == NULL)
|
||||
return; /* Empty function. */
|
||||
|
||||
tree last_stmt = tsi_stmt (tsi_last (stmts));
|
||||
|
||||
if (TREE_CODE (last_stmt) == RETURN_EXPR)
|
||||
return;
|
||||
|
||||
if (m_ret_value != NULL_TREE)
|
||||
{
|
||||
tree result_assign
|
||||
= build2 (MODIFY_EXPR, TREE_TYPE (m_ret_value), m_ret_value,
|
||||
m_ret_temp);
|
||||
|
||||
tree return_expr
|
||||
= build1 (RETURN_EXPR, TREE_TYPE (result_assign), result_assign);
|
||||
append_to_statement_list_force (return_expr, &stmts);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree return_stmt = build_stmt (RETURN_EXPR, NULL);
|
||||
append_to_statement_list_force (return_stmt, &stmts);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
brig_function::has_function_scope_var (const BrigBase* var) const
|
||||
{
|
||||
return m_function_scope_vars.find (var) != m_function_scope_vars.end ();
|
||||
}
|
213
gcc/brig/brigfrontend/brig-function.h
Normal file
213
gcc/brig/brigfrontend/brig-function.h
Normal file
|
@ -0,0 +1,213 @@
|
|||
/* brig-function.h -- declaration of brig_function class.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef BRIG_FUNCTION_H
|
||||
#define BRIG_FUNCTION_H
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "ansidecl.h"
|
||||
#include "coretypes.h"
|
||||
#include "opts.h"
|
||||
#include "tree.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "hsa-brig-format.h"
|
||||
|
||||
class brig_to_generic;
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "phsa.h"
|
||||
|
||||
typedef std::map<std::string, tree> label_index;
|
||||
typedef std::map<const BrigDirectiveVariable *, tree> variable_index;
|
||||
typedef std::vector<tree> tree_stl_vec;
|
||||
|
||||
/* There are 128 c regs and 2048 s/d/q regs each in the HSAIL. */
|
||||
#define BRIG_2_TREE_HSAIL_C_REG_COUNT (128)
|
||||
#define BRIG_2_TREE_HSAIL_S_REG_COUNT (2048)
|
||||
#define BRIG_2_TREE_HSAIL_D_REG_COUNT (2048)
|
||||
#define BRIG_2_TREE_HSAIL_Q_REG_COUNT (2048)
|
||||
#define BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT \
|
||||
(BRIG_2_TREE_HSAIL_C_REG_COUNT + BRIG_2_TREE_HSAIL_S_REG_COUNT \
|
||||
+ BRIG_2_TREE_HSAIL_D_REG_COUNT + BRIG_2_TREE_HSAIL_Q_REG_COUNT)
|
||||
|
||||
/* Holds data for the currently built GENERIC function. */
|
||||
|
||||
class brig_function
|
||||
{
|
||||
public:
|
||||
typedef std::map<const BrigDirectiveVariable *, size_t> var_offset_table;
|
||||
|
||||
private:
|
||||
struct reg_decl_index_entry
|
||||
{
|
||||
tree m_var_decl;
|
||||
};
|
||||
|
||||
public:
|
||||
brig_function (const BrigDirectiveExecutable *exec, brig_to_generic *parent);
|
||||
~brig_function ();
|
||||
|
||||
tree arg_variable (const BrigDirectiveVariable *var) const;
|
||||
void add_arg_variable (const BrigDirectiveVariable *brigVar, tree treeDecl);
|
||||
|
||||
void append_kernel_arg (const BrigDirectiveVariable *var, size_t size,
|
||||
size_t alignment);
|
||||
|
||||
size_t kernel_arg_offset (const BrigDirectiveVariable *var) const;
|
||||
|
||||
void add_id_variables ();
|
||||
|
||||
tree label (const std::string &name);
|
||||
|
||||
tree add_local_variable (std::string name, tree type);
|
||||
|
||||
tree get_m_var_declfor_reg (const BrigOperandRegister *reg);
|
||||
|
||||
bool convert_to_wg_function ();
|
||||
|
||||
void add_wi_loop (int dim, tree_stmt_iterator *header_entry,
|
||||
tree_stmt_iterator *branch_after);
|
||||
|
||||
tree emit_metadata (tree stmt_list);
|
||||
tree emit_launcher_and_metadata ();
|
||||
|
||||
tree append_statement (tree stmt);
|
||||
|
||||
void create_alloca_frame ();
|
||||
|
||||
void finish ();
|
||||
void finish_kernel ();
|
||||
|
||||
void append_return_stmt ();
|
||||
|
||||
bool has_function_scope_var (const BrigBase* var) const;
|
||||
|
||||
void analyze_calls ();
|
||||
|
||||
const BrigDirectiveExecutable *m_brig_def;
|
||||
|
||||
bool m_is_kernel;
|
||||
bool m_is_finished;
|
||||
std::string m_name;
|
||||
tree m_current_bind_expr;
|
||||
tree m_func_decl;
|
||||
tree m_entry_label_stmt;
|
||||
tree m_exit_label;
|
||||
|
||||
/* The __context function argument. */
|
||||
tree m_context_arg;
|
||||
/* The __group_base_ptr argument in the current function.
|
||||
Points to the start of the group segment for the kernel
|
||||
instance. */
|
||||
tree m_group_base_arg;
|
||||
/* The __private_base_ptr argument in the current function.
|
||||
Points to the start of the private segment. */
|
||||
tree m_private_base_arg;
|
||||
|
||||
/* The return value variable for the current function. */
|
||||
tree m_ret_value;
|
||||
|
||||
/* The offsets of the kernel arguments in the __arg blob
|
||||
pointing to the kernel argument space. */
|
||||
size_t m_next_kernarg_offset;
|
||||
|
||||
/* The largest kernel argument variable alignment. */
|
||||
size_t m_kernarg_max_align;
|
||||
|
||||
var_offset_table m_kernarg_offsets;
|
||||
|
||||
/* Argument variables in the currently handled binding expression
|
||||
(argument segment). */
|
||||
variable_index m_arg_variables;
|
||||
|
||||
/* The brig variable for the function return value. */
|
||||
const BrigDirectiveVariable *m_ret_value_brig_var;
|
||||
|
||||
/* The function local temporary variable for the return value. */
|
||||
tree m_ret_temp;
|
||||
|
||||
/* Labels in the current function are collected here so we can refer
|
||||
to them from jumps before they have been placed to the function. */
|
||||
label_index m_label_index;
|
||||
|
||||
/* If the kernel contains at least one barrier, this is set to true. */
|
||||
bool m_has_barriers;
|
||||
|
||||
/* True if the function has at least one alloca instruction. */
|
||||
bool m_has_allocas;
|
||||
|
||||
/* If the kernel containts at least one function call that _may_
|
||||
contain a barrier call, this is set to true. */
|
||||
bool m_has_function_calls_with_barriers;
|
||||
|
||||
/* Set to true after this function has been analyzed for barrier and
|
||||
dispatch packet instruction usage in the final call graph analysis. */
|
||||
bool m_calls_analyzed;
|
||||
|
||||
/* True in case the function was successfully converted to a WG function. */
|
||||
bool m_is_wg_function;
|
||||
|
||||
/* Work-item ID related variables are cached in the entry of the kernel
|
||||
function in order to use them directly in address computations, leading
|
||||
to more efficient optimizations. The references to the local variables
|
||||
are stored here. */
|
||||
tree m_local_id_vars[3];
|
||||
tree m_cur_wg_size_vars[3];
|
||||
tree m_wg_id_vars[3];
|
||||
tree m_wg_size_vars[3];
|
||||
tree m_grid_size_vars[3];
|
||||
|
||||
/* Set to true in case the kernel contains at least one dispatch packet
|
||||
(work-item ID-related) builtin call that could not be expanded to
|
||||
tree nodes. */
|
||||
bool m_has_unexpanded_dp_builtins;
|
||||
|
||||
/* Points to the instruction after which the real kernel code starts.
|
||||
Usually points to the last WI ID variable initialization statement. */
|
||||
tree_stmt_iterator m_kernel_entry;
|
||||
|
||||
/* True if we are currently generating the contents of an arg block. */
|
||||
bool m_generating_arg_block;
|
||||
|
||||
/* A collection of function scope variables seen so far for resolving
|
||||
variable references vs. module scope declarations. */
|
||||
std::set<const BrigBase*> m_function_scope_vars;
|
||||
|
||||
/* The functions called by this function. */
|
||||
std::vector<tree> m_called_functions;
|
||||
|
||||
brig_to_generic *m_parent;
|
||||
/* The metadata of the function that should be stored with the binary and
|
||||
passed to the HSA runtime: */
|
||||
phsa_descriptor m_descriptor;
|
||||
|
||||
private:
|
||||
/* Bookkeeping for the different HSA registers and their tree declarations
|
||||
for the currently generated function. */
|
||||
reg_decl_index_entry *m_regs[BRIG_2_TREE_HSAIL_TOTAL_REG_COUNT];
|
||||
};
|
||||
|
||||
#endif
|
58
gcc/brig/brigfrontend/brig-inst-mod-handler.cc
Normal file
58
gcc/brig/brigfrontend/brig-inst-mod-handler.cc
Normal file
|
@ -0,0 +1,58 @@
|
|||
/* brig-inst-mod-handler.cc -- brig rounding moded instruction handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
|
||||
#include "gimple-expr.h"
|
||||
#include "errors.h"
|
||||
|
||||
size_t
|
||||
brig_inst_mod_handler::generate (const BrigBase *base)
|
||||
{
|
||||
brig_basic_inst_handler basic_handler (m_parent);
|
||||
return basic_handler (base);
|
||||
}
|
||||
|
||||
const BrigAluModifier8_t *
|
||||
brig_inst_mod_handler::modifier (const BrigBase *base) const
|
||||
{
|
||||
const BrigInstMod *inst = (const BrigInstMod *) base;
|
||||
return &inst->modifier;
|
||||
}
|
||||
|
||||
const BrigRound8_t *
|
||||
brig_inst_mod_handler::round (const BrigBase *base) const
|
||||
{
|
||||
const BrigInstMod *inst = (const BrigInstMod *) base;
|
||||
return &inst->round;
|
||||
}
|
||||
|
||||
/* This used to inject fesetround () calls to control the rounding mode of the
|
||||
actual executed floating point operation. It turned out that supporting
|
||||
conversions using fesetround calls won't work in gcc due to it not being
|
||||
able to restrict code motions across calls at the moment. This
|
||||
functionality is therefore disabled for now until a better solution is
|
||||
found or if fesetround () is fixed in gcc. */
|
||||
size_t
|
||||
brig_inst_mod_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
return generate (base);
|
||||
}
|
37
gcc/brig/brigfrontend/brig-label-handler.cc
Normal file
37
gcc/brig/brigfrontend/brig-label-handler.cc
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* brig-label-handler.cc -- brig label directive handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
|
||||
size_t
|
||||
brig_directive_label_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigDirectiveLabel *brig_label = (const BrigDirectiveLabel *) base;
|
||||
|
||||
const BrigData *label_name = m_parent.get_brig_data_entry (brig_label->name);
|
||||
|
||||
std::string label_str ((const char *) (label_name->bytes),
|
||||
label_name->byteCount);
|
||||
|
||||
tree stmt = build_stmt (LABEL_EXPR, m_parent.m_cf->label (label_str));
|
||||
m_parent.m_cf->append_statement (stmt);
|
||||
return base->byteCount;
|
||||
}
|
84
gcc/brig/brigfrontend/brig-lane-inst-handler.cc
Normal file
84
gcc/brig/brigfrontend/brig-lane-inst-handler.cc
Normal file
|
@ -0,0 +1,84 @@
|
|||
/* brig-lane-inst-handler.cc -- brig lane instruction handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "errors.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "brig-util.h"
|
||||
|
||||
brig_lane_inst_handler::brig_lane_inst_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_lane_inst_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigInstLane &inst = *(const BrigInstLane *) base;
|
||||
tree_stl_vec operands = build_operands (inst.base);
|
||||
|
||||
tree expr = NULL_TREE;
|
||||
if (inst.base.opcode == BRIG_OPCODE_ACTIVELANECOUNT)
|
||||
{
|
||||
/* Because we are fixed to single WI per wave, it's enough to
|
||||
just check the src value of the single work item itself. */
|
||||
expr = build2 (NE_EXPR, uint32_type_node,
|
||||
build_zero_cst (uint32_type_node), operands[1]);
|
||||
}
|
||||
else if (inst.base.opcode == BRIG_OPCODE_ACTIVELANEID)
|
||||
{
|
||||
expr = build_zero_cst (uint32_type_node);
|
||||
}
|
||||
else if (inst.base.opcode == BRIG_OPCODE_ACTIVELANEMASK)
|
||||
{
|
||||
tree u64_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U64);
|
||||
tree zero_cst = build_zero_cst (u64_type);
|
||||
expr = build2 (NE_EXPR, u64_type, zero_cst, operands[1]);
|
||||
|
||||
tree_stl_vec elements;
|
||||
elements.push_back (expr);
|
||||
elements.push_back (zero_cst);
|
||||
elements.push_back (zero_cst);
|
||||
elements.push_back (zero_cst);
|
||||
|
||||
expr = pack (elements);
|
||||
}
|
||||
else if (inst.base.opcode == BRIG_OPCODE_ACTIVELANEPERMUTE)
|
||||
{
|
||||
tree src = operands[1];
|
||||
tree identity = operands[3];
|
||||
tree use_identity = operands[4];
|
||||
|
||||
/* When WAVESIZE is 1, we either select the src of the work-item
|
||||
itself or 'identity' in case use_identity is 1. */
|
||||
|
||||
tree cmp = build2 (EQ_EXPR, uint32_type_node,
|
||||
build_int_cstu (uint32_type_node, 1), use_identity);
|
||||
|
||||
expr = build3 (COND_EXPR, TREE_TYPE (src), cmp, identity, src);
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
build_output_assignment (inst.base, operands[0], expr);
|
||||
|
||||
return base->byteCount;
|
||||
}
|
44
gcc/brig/brigfrontend/brig-machine.c
Normal file
44
gcc/brig/brigfrontend/brig-machine.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
/* brig-machine.c -- gccbrig machine queries
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "brig-machine.h"
|
||||
|
||||
/* Return the numerical address space id for the segment in the current
|
||||
target. Currently a dummy function that always returns 0, serves as
|
||||
a placeholder for multi-AS machines. */
|
||||
|
||||
unsigned
|
||||
gccbrig_get_target_addr_space_id (BrigSegment8_t)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the WAVESIZE for the current target. For now a dummy placeholder
|
||||
returning always 1. */
|
||||
|
||||
unsigned
|
||||
gccbrig_get_target_wavesize ()
|
||||
{
|
||||
return 1;
|
||||
}
|
33
gcc/brig/brigfrontend/brig-machine.h
Normal file
33
gcc/brig/brigfrontend/brig-machine.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/* brig-machine.h -- gccbrig machine queries
|
||||
Copyright (C) 2016 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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_BRIG_MACHINE_H
|
||||
#define GCC_BRIG_MACHINE_H
|
||||
|
||||
#include "hsa-brig-format.h"
|
||||
|
||||
/* These functions should be eventually converted to machine info queries and
|
||||
redefined at backends. At that point make these functions delegate to
|
||||
those. */
|
||||
|
||||
unsigned gccbrig_get_target_addr_space_id (BrigSegment8_t segment);
|
||||
|
||||
unsigned gccbrig_get_target_wavesize ();
|
||||
|
||||
#endif
|
180
gcc/brig/brigfrontend/brig-mem-inst-handler.cc
Normal file
180
gcc/brig/brigfrontend/brig-mem-inst-handler.cc
Normal file
|
@ -0,0 +1,180 @@
|
|||
/* brig-mem-inst-handler.cc -- brig memory inst handler
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
|
||||
#include "errors.h"
|
||||
#include "brig-util.h"
|
||||
#include "gimple-expr.h"
|
||||
#include "print-tree.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "convert.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
tree
|
||||
brig_mem_inst_handler::build_mem_access (const BrigInstBase *brig_inst,
|
||||
tree addr, tree data)
|
||||
{
|
||||
bool is_load = brig_inst->opcode == BRIG_OPCODE_LD;
|
||||
bool is_store = brig_inst->opcode == BRIG_OPCODE_ST;
|
||||
|
||||
if (!is_load && !is_store)
|
||||
gcc_unreachable ();
|
||||
|
||||
tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst->type);
|
||||
|
||||
if (VECTOR_TYPE_P (TREE_TYPE (data)))
|
||||
instr_type = TREE_TYPE (data);
|
||||
|
||||
tree ptype = build_pointer_type (instr_type);
|
||||
|
||||
/* The HSAIL mem instructions are unaligned by default.
|
||||
TODO: exploit the align modifier, it should lead to faster code.
|
||||
*/
|
||||
tree unaligned_type = build_aligned_type (instr_type, 8);
|
||||
|
||||
/* Create a mem ref from the previous result, without offset. */
|
||||
tree mem_ref
|
||||
= build2 (MEM_REF, unaligned_type, addr, build_int_cst (ptype, 0));
|
||||
|
||||
if (is_load)
|
||||
{
|
||||
/* Add a temporary variable so there won't be multiple
|
||||
reads in case of vector unpack. */
|
||||
mem_ref = add_temp_var ("mem_read", mem_ref);
|
||||
return build_output_assignment (*brig_inst, data, mem_ref);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree stmt = build2 (MODIFY_EXPR, TREE_TYPE (mem_ref), mem_ref, data);
|
||||
return m_parent.m_cf->append_statement (stmt);
|
||||
}
|
||||
return mem_ref;
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_mem_inst_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigInstBase *brig_inst
|
||||
= (const BrigInstBase *) &((const BrigInstBasic *) base)->base;
|
||||
|
||||
if (brig_inst->opcode == BRIG_OPCODE_ALLOCA)
|
||||
{
|
||||
tree_stl_vec operands = build_operands (*brig_inst);
|
||||
size_t alignment = 1;
|
||||
const BrigInstMem *mem_inst = (const BrigInstMem *) brig_inst;
|
||||
if (mem_inst->align != BRIG_ALIGNMENT_NONE)
|
||||
{
|
||||
alignment = 1 << (mem_inst->align - 1);
|
||||
}
|
||||
|
||||
tree align_opr = build_int_cstu (size_type_node, alignment);
|
||||
tree_stl_vec inputs;
|
||||
inputs.push_back (operands[1]);
|
||||
inputs.push_back (align_opr);
|
||||
tree builtin_call
|
||||
= expand_or_call_builtin (BRIG_OPCODE_ALLOCA, BRIG_TYPE_U32,
|
||||
uint32_type_node, inputs);
|
||||
build_output_assignment (*brig_inst, operands[0], builtin_call);
|
||||
m_parent.m_cf->m_has_allocas = true;
|
||||
return base->byteCount;
|
||||
}
|
||||
|
||||
tree instr_type = gccbrig_tree_type_for_hsa_type (brig_inst->type);
|
||||
|
||||
const BrigData *operand_entries
|
||||
= m_parent.get_brig_data_entry (brig_inst->operands);
|
||||
|
||||
uint32_t data_operand_offset;
|
||||
memcpy (&data_operand_offset, &operand_entries->bytes, 4);
|
||||
|
||||
const BrigBase *operand
|
||||
= m_parent.get_brig_operand_entry (data_operand_offset);
|
||||
|
||||
const BrigData *operandData = NULL;
|
||||
|
||||
bool is_store = brig_inst->opcode == BRIG_OPCODE_ST;
|
||||
|
||||
bool is_three_element_vector_access
|
||||
= operand->kind == BRIG_KIND_OPERAND_OPERAND_LIST
|
||||
&& (operandData = m_parent.get_brig_data_entry
|
||||
(((const BrigOperandOperandList *) operand)->elements))
|
||||
&& operandData->byteCount / 4 == 3;
|
||||
|
||||
if (is_three_element_vector_access)
|
||||
{
|
||||
/* We need to scalarize the 3-element vector accesses here
|
||||
because gcc assumes the GENERIC vector datatypes are of two exponent
|
||||
size internally. */
|
||||
size_t bytes = operandData->byteCount;
|
||||
const BrigOperandOffset32_t *operand_ptr
|
||||
= (const BrigOperandOffset32_t *) operandData->bytes;
|
||||
|
||||
uint32_t addr_operand_offset;
|
||||
memcpy (&addr_operand_offset, &operand_entries->bytes + 4, 4);
|
||||
|
||||
const BrigOperandAddress *addr_operand
|
||||
= (const BrigOperandAddress *) m_parent.get_brig_operand_entry
|
||||
(addr_operand_offset);
|
||||
|
||||
tree address_base = build_address_operand (*brig_inst, *addr_operand);
|
||||
|
||||
uint32_t address_offset = 0;
|
||||
while (bytes > 0)
|
||||
{
|
||||
BrigOperandOffset32_t offset = *operand_ptr;
|
||||
const BrigBase *operand_element
|
||||
= m_parent.get_brig_operand_entry (offset);
|
||||
tree data
|
||||
= build_tree_operand (*brig_inst, *operand_element, instr_type);
|
||||
|
||||
tree ptr_offset = build_int_cst (size_type_node, address_offset);
|
||||
tree address = build2 (POINTER_PLUS_EXPR, TREE_TYPE (address_base),
|
||||
address_base, ptr_offset);
|
||||
|
||||
if (is_store && TREE_TYPE (data) != instr_type)
|
||||
{
|
||||
if (int_size_in_bytes (TREE_TYPE (data))
|
||||
== int_size_in_bytes (instr_type)
|
||||
&& !INTEGRAL_TYPE_P (instr_type))
|
||||
data = build1 (VIEW_CONVERT_EXPR, instr_type, data);
|
||||
else
|
||||
data = convert (instr_type, data);
|
||||
}
|
||||
|
||||
build_mem_access (brig_inst, address, data);
|
||||
|
||||
address_offset += int_size_in_bytes (instr_type);
|
||||
++operand_ptr;
|
||||
bytes -= 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tree_stl_vec operands = build_operands (*brig_inst);
|
||||
|
||||
tree &data = operands.at (0);
|
||||
tree &addr = operands.at (1);
|
||||
build_mem_access (brig_inst, addr, data);
|
||||
}
|
||||
|
||||
return base->byteCount;
|
||||
}
|
41
gcc/brig/brigfrontend/brig-module-handler.cc
Normal file
41
gcc/brig/brigfrontend/brig-module-handler.cc
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* brig-module-handler.cc -- brig module directive handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
size_t
|
||||
brig_directive_module_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigDirectiveModule* mod = (const BrigDirectiveModule*)base;
|
||||
m_parent.m_module_name = m_parent.get_string (mod->name).substr (1);
|
||||
if (mod->hsailMajor != 1 || mod->hsailMinor != 0)
|
||||
fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE " "
|
||||
"HSAIL version not supported. HSAIL 1.0 required.");
|
||||
if (mod->machineModel != BRIG_MACHINE_LARGE)
|
||||
fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE " "
|
||||
"Only HSA 'large' machine model supported.");
|
||||
/* Do not check for the profile as the runtime conformance suite tests
|
||||
with 'full' profile BRIGs even though they don't use any full profile
|
||||
features. This allows us to run the conformance suite with the
|
||||
BRIG FE. */
|
||||
return base->byteCount;
|
||||
}
|
93
gcc/brig/brigfrontend/brig-queue-inst-handler.cc
Normal file
93
gcc/brig/brigfrontend/brig-queue-inst-handler.cc
Normal file
|
@ -0,0 +1,93 @@
|
|||
/* brig-queue-inst-handler.cc -- brig user mode queue related instruction
|
||||
handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "brig-util.h"
|
||||
#include "convert.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "errors.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "brig-builtins.h"
|
||||
|
||||
brig_queue_inst_handler::brig_queue_inst_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_queue_inst_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigInstBase &inst_base = *(const BrigInstBase *) base;
|
||||
|
||||
tree_stl_vec operands = build_operands (inst_base);
|
||||
|
||||
if (inst_base.opcode == BRIG_OPCODE_LDQUEUEWRITEINDEX
|
||||
|| inst_base.opcode == BRIG_OPCODE_LDQUEUEREADINDEX)
|
||||
{
|
||||
tree builtin
|
||||
= inst_base.opcode == BRIG_OPCODE_LDQUEUEWRITEINDEX
|
||||
? builtin_decl_explicit (BUILT_IN_HSAIL_LDQUEUEWRITEINDEX)
|
||||
: builtin_decl_explicit (BUILT_IN_HSAIL_LDQUEUEREADINDEX);
|
||||
|
||||
tree expr
|
||||
= call_builtin (builtin, 1, uint64_type_node,
|
||||
uint64_type_node, operands[1]);
|
||||
build_output_assignment (inst_base, operands[0], expr);
|
||||
}
|
||||
else if (inst_base.opcode == BRIG_OPCODE_STQUEUEWRITEINDEX
|
||||
|| inst_base.opcode == BRIG_OPCODE_STQUEUEREADINDEX)
|
||||
{
|
||||
tree builtin
|
||||
= inst_base.opcode == BRIG_OPCODE_STQUEUEWRITEINDEX
|
||||
? builtin_decl_explicit (BUILT_IN_HSAIL_STQUEUEWRITEINDEX)
|
||||
: builtin_decl_explicit (BUILT_IN_HSAIL_STQUEUEREADINDEX);
|
||||
|
||||
call_builtin (builtin, 2, void_type_node,
|
||||
uint64_type_node, operands[0], uint64_type_node,
|
||||
operands[1]);
|
||||
}
|
||||
else if (inst_base.opcode == BRIG_OPCODE_ADDQUEUEWRITEINDEX)
|
||||
{
|
||||
tree builtin = builtin_decl_explicit (BUILT_IN_HSAIL_ADDQUEUEWRITEINDEX);
|
||||
|
||||
tree expr = call_builtin (builtin, 2,
|
||||
uint64_type_node, uint64_type_node, operands[1],
|
||||
uint64_type_node, operands[2]);
|
||||
build_output_assignment (inst_base, operands[0], expr);
|
||||
}
|
||||
else if (inst_base.opcode == BRIG_OPCODE_CASQUEUEWRITEINDEX)
|
||||
{
|
||||
tree builtin = builtin_decl_explicit (BUILT_IN_HSAIL_CASQUEUEWRITEINDEX);
|
||||
|
||||
tree expr
|
||||
= call_builtin (builtin, 3, uint64_type_node,
|
||||
uint64_type_node, operands[1], uint64_type_node,
|
||||
operands[2], uint64_type_node, operands[3]);
|
||||
build_output_assignment (inst_base, operands[0], expr);
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
return base->byteCount;
|
||||
}
|
146
gcc/brig/brigfrontend/brig-seg-inst-handler.cc
Normal file
146
gcc/brig/brigfrontend/brig-seg-inst-handler.cc
Normal file
|
@ -0,0 +1,146 @@
|
|||
/* brig-seg-inst-handler.cc -- brig segment related instruction handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "brig-util.h"
|
||||
#include "convert.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "errors.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
brig_seg_inst_handler::brig_seg_inst_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_seg_inst_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigInstBase &inst_base = *(const BrigInstBase *) base;
|
||||
|
||||
std::vector<tree> operands = build_operands (inst_base);
|
||||
|
||||
tree expr = NULL_TREE;
|
||||
|
||||
if (inst_base.opcode == BRIG_OPCODE_STOF)
|
||||
{
|
||||
const BrigInstSegCvt &inst = *(const BrigInstSegCvt *) base;
|
||||
|
||||
if (inst.segment == BRIG_SEGMENT_GROUP)
|
||||
expr = build2 (PLUS_EXPR, size_type_node,
|
||||
convert_to_integer (size_type_node,
|
||||
m_parent.m_cf->m_group_base_arg),
|
||||
convert_to_integer (size_type_node, operands[1]));
|
||||
else if (inst.segment == BRIG_SEGMENT_PRIVATE
|
||||
|| inst.segment == BRIG_SEGMENT_SPILL)
|
||||
expr = build2 (PLUS_EXPR, size_type_node,
|
||||
convert_to_integer (size_type_node,
|
||||
m_parent.m_cf->m_private_base_arg),
|
||||
convert_to_integer (size_type_node, operands[1]));
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
if (!(inst.modifier & BRIG_SEG_CVT_NONULL))
|
||||
{
|
||||
/* Need to convert the null value. -1 is used for 32b segments,
|
||||
and 0 for flat/global. */
|
||||
tree cmp
|
||||
= build2 (EQ_EXPR, uint32_type_node,
|
||||
build_int_cstu (uint32_type_node, -1), operands[1]);
|
||||
|
||||
tree null_check = build3 (COND_EXPR, size_type_node, cmp,
|
||||
build_int_cstu (size_type_node, 0), expr);
|
||||
|
||||
expr = null_check;
|
||||
}
|
||||
}
|
||||
else if (inst_base.opcode == BRIG_OPCODE_FTOS)
|
||||
{
|
||||
const BrigInstSegCvt &inst = *(const BrigInstSegCvt *) base;
|
||||
|
||||
if (inst.segment == BRIG_SEGMENT_GROUP)
|
||||
expr = build2 (MINUS_EXPR, size_type_node,
|
||||
convert_to_integer (size_type_node,
|
||||
m_parent.m_cf->m_group_base_arg),
|
||||
convert_to_integer (size_type_node, operands[1]));
|
||||
else if (inst.segment == BRIG_SEGMENT_PRIVATE)
|
||||
expr = build2 (MINUS_EXPR, size_type_node,
|
||||
convert_to_integer (size_type_node,
|
||||
m_parent.m_cf->m_private_base_arg),
|
||||
convert_to_integer (size_type_node, operands[1]));
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
if (!(inst.modifier & BRIG_SEG_CVT_NONULL))
|
||||
{
|
||||
/* Need to convert the null value. -1 is used for 32b segments,
|
||||
and 0 for flat/global. */
|
||||
tree cmp = build2 (EQ_EXPR, size_type_node,
|
||||
build_int_cstu (size_type_node, 0), operands[1]);
|
||||
|
||||
tree null_check
|
||||
= build3 (COND_EXPR, size_type_node, cmp,
|
||||
build_int_cstu (uint32_type_node, -1), expr);
|
||||
expr = null_check;
|
||||
}
|
||||
}
|
||||
else if (inst_base.opcode == BRIG_OPCODE_NULLPTR)
|
||||
{
|
||||
const BrigInstSeg &inst = *(const BrigInstSeg *) base;
|
||||
if (inst.segment == BRIG_SEGMENT_GLOBAL
|
||||
|| inst.segment == BRIG_SEGMENT_FLAT
|
||||
|| inst.segment == BRIG_SEGMENT_READONLY)
|
||||
expr = build_int_cstu (uint64_type_node, 0);
|
||||
else
|
||||
expr = build_int_cstu (uint32_type_node, -1);
|
||||
}
|
||||
else if (inst_base.opcode == BRIG_OPCODE_SEGMENTP)
|
||||
{
|
||||
const BrigInstSegCvt &inst = *(const BrigInstSegCvt *) base;
|
||||
|
||||
tree builtin = NULL_TREE;
|
||||
switch (inst.segment)
|
||||
{
|
||||
case BRIG_SEGMENT_GLOBAL:
|
||||
builtin = builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_GLOBAL);
|
||||
break;
|
||||
case BRIG_SEGMENT_GROUP:
|
||||
builtin = builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_GROUP);
|
||||
break;
|
||||
case BRIG_SEGMENT_PRIVATE:
|
||||
builtin = builtin_decl_explicit (BUILT_IN_HSAIL_SEGMENTP_PRIVATE);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
expr = call_builtin (builtin, 2,
|
||||
uint32_type_node, uint64_type_node, operands[1],
|
||||
ptr_type_node, m_parent.m_cf->m_context_arg);
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
build_output_assignment (inst_base, operands[0], expr);
|
||||
return base->byteCount;
|
||||
}
|
42
gcc/brig/brigfrontend/brig-signal-inst-handler.cc
Normal file
42
gcc/brig/brigfrontend/brig-signal-inst-handler.cc
Normal file
|
@ -0,0 +1,42 @@
|
|||
/* brig-signal-inst-handler.cc -- brig signal instruction handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "brig-util.h"
|
||||
#include "fold-const.h"
|
||||
#include "diagnostic.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "print-tree.h"
|
||||
#include "convert.h"
|
||||
#include "langhooks.h"
|
||||
#include "gimple-expr.h"
|
||||
|
||||
size_t
|
||||
brig_signal_inst_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigInstSignal *inst = (const BrigInstSignal *) base;
|
||||
BrigAtomicOperation8_t atomic_opcode;
|
||||
atomic_opcode = inst->signalOperation;
|
||||
|
||||
return generate_tree (inst->base, atomic_opcode);
|
||||
}
|
796
gcc/brig/brigfrontend/brig-to-generic.cc
Normal file
796
gcc/brig/brigfrontend/brig-to-generic.cc
Normal file
|
@ -0,0 +1,796 @@
|
|||
/* brig2tree.cc -- brig to gcc generic/gimple tree conversion
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "target.h"
|
||||
#include "function.h"
|
||||
#include "brig-to-generic.h"
|
||||
#include "stringpool.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "toplev.h"
|
||||
#include "gimplify.h"
|
||||
#include "gimple-expr.h"
|
||||
#include "print-tree.h"
|
||||
#include "hsa-brig-format.h"
|
||||
#include "stor-layout.h"
|
||||
#include "diagnostic-core.h"
|
||||
#include "brig-code-entry-handler.h"
|
||||
#include "brig-machine.h"
|
||||
#include "brig-util.h"
|
||||
#include "phsa.h"
|
||||
#include "tree-pretty-print.h"
|
||||
#include "dumpfile.h"
|
||||
#include "tree-cfg.h"
|
||||
#include "errors.h"
|
||||
#include "fold-const.h"
|
||||
#include "cgraph.h"
|
||||
#include "dumpfile.h"
|
||||
#include "tree-pretty-print.h"
|
||||
|
||||
extern int gccbrig_verbose;
|
||||
|
||||
tree brig_to_generic::s_fp16_type;
|
||||
tree brig_to_generic::s_fp32_type;
|
||||
tree brig_to_generic::s_fp64_type;
|
||||
|
||||
brig_to_generic::brig_to_generic ()
|
||||
: m_cf (NULL), m_brig (NULL), m_next_group_offset (0),
|
||||
m_next_private_offset (0)
|
||||
{
|
||||
m_globals = NULL_TREE;
|
||||
|
||||
/* Initialize the basic REAL types.
|
||||
This doesn't work straight away because most of the targets
|
||||
do not support fp16 natively. Let's by default convert
|
||||
to fp32 and back before and after each instruction (handle it as
|
||||
a storage format only), and later add an optimization pass
|
||||
that removes the extra converts (in case of multiple fp16 ops
|
||||
in a row). */
|
||||
s_fp16_type = make_node (REAL_TYPE);
|
||||
TYPE_PRECISION (s_fp16_type) = 16;
|
||||
TYPE_SIZE (s_fp16_type) = bitsize_int (16);
|
||||
TYPE_SIZE_UNIT (s_fp16_type) = size_int (2);
|
||||
SET_TYPE_ALIGN (s_fp16_type, 16);
|
||||
layout_type (s_fp16_type);
|
||||
|
||||
s_fp32_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_F32);
|
||||
s_fp64_type = gccbrig_tree_type_for_hsa_type (BRIG_TYPE_F64);
|
||||
|
||||
/* TODO: (machine)query the preferred rounding mode that is set by
|
||||
the machine by default. This can be redefined by each BRIG module
|
||||
header. */
|
||||
m_default_float_rounding_mode = BRIG_ROUND_FLOAT_ZERO;
|
||||
|
||||
m_dump_file = dump_begin (TDI_original, &m_dump_flags);
|
||||
}
|
||||
|
||||
class unimplemented_entry_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
unimplemented_entry_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
operator () (const BrigBase *base)
|
||||
{
|
||||
gcc_unreachable ();
|
||||
return base->byteCount;
|
||||
}
|
||||
};
|
||||
|
||||
/* Handler for entries that can be (and are) safely skipped for the purposes
|
||||
of GENERIC generation. */
|
||||
|
||||
class skipped_entry_handler : public brig_code_entry_handler
|
||||
{
|
||||
public:
|
||||
skipped_entry_handler (brig_to_generic &parent)
|
||||
: brig_code_entry_handler (parent)
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
operator () (const BrigBase *base)
|
||||
{
|
||||
return base->byteCount;
|
||||
}
|
||||
};
|
||||
|
||||
/* Parses the given BRIG blob. */
|
||||
|
||||
void
|
||||
brig_to_generic::parse (const char *brig_blob)
|
||||
{
|
||||
m_brig = brig_blob;
|
||||
m_brig_blobs.push_back (brig_blob);
|
||||
|
||||
const BrigModuleHeader *mheader = (const BrigModuleHeader *) brig_blob;
|
||||
|
||||
if (strncmp (mheader->identification, "HSA BRIG", 8) != 0)
|
||||
fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE
|
||||
"Unrecognized file format.");
|
||||
if (mheader->brigMajor != 1 || mheader->brigMinor != 0)
|
||||
fatal_error (UNKNOWN_LOCATION, PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE
|
||||
"BRIG version not supported. BRIG 1.0 required.");
|
||||
|
||||
m_data = m_code = m_operand = NULL;
|
||||
|
||||
/* Find the positions of the different sections. */
|
||||
for (uint32_t sec = 0; sec < mheader->sectionCount; ++sec)
|
||||
{
|
||||
uint64_t offset
|
||||
= ((const uint64_t *) (brig_blob + mheader->sectionIndex))[sec];
|
||||
|
||||
const BrigSectionHeader *section_header
|
||||
= (const BrigSectionHeader *) (brig_blob + offset);
|
||||
|
||||
std::string name ((const char *) (§ion_header->name),
|
||||
section_header->nameLength);
|
||||
|
||||
if (sec == BRIG_SECTION_INDEX_DATA && name == "hsa_data")
|
||||
{
|
||||
m_data = (const char *) section_header;
|
||||
m_data_size = section_header->byteCount;
|
||||
}
|
||||
else if (sec == BRIG_SECTION_INDEX_CODE && name == "hsa_code")
|
||||
{
|
||||
m_code = (const char *) section_header;
|
||||
m_code_size = section_header->byteCount;
|
||||
}
|
||||
else if (sec == BRIG_SECTION_INDEX_OPERAND && name == "hsa_operand")
|
||||
{
|
||||
m_operand = (const char *) section_header;
|
||||
m_operand_size = section_header->byteCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_code == NULL)
|
||||
gcc_unreachable ();
|
||||
if (m_data == NULL)
|
||||
gcc_unreachable ();
|
||||
if (m_operand == NULL)
|
||||
gcc_unreachable ();
|
||||
|
||||
brig_basic_inst_handler inst_handler (*this);
|
||||
brig_branch_inst_handler branch_inst_handler (*this);
|
||||
brig_cvt_inst_handler cvt_inst_handler (*this);
|
||||
brig_seg_inst_handler seg_inst_handler (*this);
|
||||
brig_copy_move_inst_handler copy_move_inst_handler (*this);
|
||||
brig_signal_inst_handler signal_inst_handler (*this);
|
||||
brig_atomic_inst_handler atomic_inst_handler (*this);
|
||||
brig_cmp_inst_handler cmp_inst_handler (*this);
|
||||
brig_mem_inst_handler mem_inst_handler (*this);
|
||||
brig_inst_mod_handler inst_mod_handler (*this);
|
||||
brig_directive_label_handler label_handler (*this);
|
||||
brig_directive_variable_handler var_handler (*this);
|
||||
brig_directive_fbarrier_handler fbar_handler (*this);
|
||||
brig_directive_comment_handler comment_handler (*this);
|
||||
brig_directive_function_handler func_handler (*this);
|
||||
brig_directive_control_handler control_handler (*this);
|
||||
brig_directive_arg_block_handler arg_block_handler (*this);
|
||||
brig_directive_module_handler module_handler (*this);
|
||||
brig_lane_inst_handler lane_inst_handler (*this);
|
||||
brig_queue_inst_handler queue_inst_handler (*this);
|
||||
skipped_entry_handler skipped_handler (*this);
|
||||
unimplemented_entry_handler unimplemented_handler (*this);
|
||||
|
||||
struct code_entry_handler_info
|
||||
{
|
||||
BrigKind kind;
|
||||
brig_code_entry_handler *handler;
|
||||
};
|
||||
|
||||
/* TODO: Convert to a hash table / map. For now, put the more common
|
||||
entries to the top to keep the scan fast on average. */
|
||||
code_entry_handler_info handlers[]
|
||||
= {{BRIG_KIND_INST_BASIC, &inst_handler},
|
||||
{BRIG_KIND_INST_CMP, &cmp_inst_handler},
|
||||
{BRIG_KIND_INST_MEM, &mem_inst_handler},
|
||||
{BRIG_KIND_INST_MOD, &inst_mod_handler},
|
||||
{BRIG_KIND_INST_CVT, &cvt_inst_handler},
|
||||
{BRIG_KIND_INST_SEG_CVT, &seg_inst_handler},
|
||||
{BRIG_KIND_INST_SEG, &seg_inst_handler},
|
||||
{BRIG_KIND_INST_ADDR, ©_move_inst_handler},
|
||||
{BRIG_KIND_INST_SOURCE_TYPE, ©_move_inst_handler},
|
||||
{BRIG_KIND_INST_ATOMIC, &atomic_inst_handler},
|
||||
{BRIG_KIND_INST_SIGNAL, &signal_inst_handler},
|
||||
{BRIG_KIND_INST_BR, &branch_inst_handler},
|
||||
{BRIG_KIND_INST_LANE, &lane_inst_handler},
|
||||
{BRIG_KIND_INST_QUEUE, &queue_inst_handler},
|
||||
/* Assuming fences are not needed. FIXME: call builtins
|
||||
when porting to a platform where they are. */
|
||||
{BRIG_KIND_INST_MEM_FENCE, &skipped_handler},
|
||||
{BRIG_KIND_DIRECTIVE_LABEL, &label_handler},
|
||||
{BRIG_KIND_DIRECTIVE_VARIABLE, &var_handler},
|
||||
{BRIG_KIND_DIRECTIVE_ARG_BLOCK_START, &arg_block_handler},
|
||||
{BRIG_KIND_DIRECTIVE_ARG_BLOCK_END, &arg_block_handler},
|
||||
{BRIG_KIND_DIRECTIVE_FBARRIER, &fbar_handler},
|
||||
{BRIG_KIND_DIRECTIVE_COMMENT, &comment_handler},
|
||||
{BRIG_KIND_DIRECTIVE_KERNEL, &func_handler},
|
||||
{BRIG_KIND_DIRECTIVE_SIGNATURE, &func_handler},
|
||||
{BRIG_KIND_DIRECTIVE_FUNCTION, &func_handler},
|
||||
{BRIG_KIND_DIRECTIVE_INDIRECT_FUNCTION, &func_handler},
|
||||
{BRIG_KIND_DIRECTIVE_MODULE, &module_handler},
|
||||
/* Skipping debug locations for now as not needed for conformance. */
|
||||
{BRIG_KIND_DIRECTIVE_LOC, &skipped_handler},
|
||||
/* There are no supported pragmas at this moment. */
|
||||
{BRIG_KIND_DIRECTIVE_PRAGMA, &skipped_handler},
|
||||
{BRIG_KIND_DIRECTIVE_CONTROL, &control_handler},
|
||||
{BRIG_KIND_DIRECTIVE_EXTENSION, &skipped_handler}};
|
||||
|
||||
const BrigSectionHeader *csection_header = (const BrigSectionHeader *) m_code;
|
||||
|
||||
for (size_t b = csection_header->headerByteCount; b < m_code_size;)
|
||||
{
|
||||
const BrigBase *entry = (const BrigBase *) (m_code + b);
|
||||
|
||||
brig_code_entry_handler *handler = &unimplemented_handler;
|
||||
|
||||
if (m_cf != NULL && b >= m_cf->m_brig_def->nextModuleEntry)
|
||||
finish_function (); /* The function definition ended. */
|
||||
|
||||
/* Find a handler. */
|
||||
for (size_t i = 0;
|
||||
i < sizeof (handlers) / sizeof (code_entry_handler_info); ++i)
|
||||
{
|
||||
if (handlers[i].kind == entry->kind)
|
||||
handler = handlers[i].handler;
|
||||
}
|
||||
b += (*handler) (entry);
|
||||
continue;
|
||||
}
|
||||
|
||||
finish_function ();
|
||||
}
|
||||
|
||||
const BrigData *
|
||||
brig_to_generic::get_brig_data_entry (size_t entry_offset) const
|
||||
{
|
||||
return (const BrigData *) (m_data + entry_offset);
|
||||
}
|
||||
|
||||
const BrigBase *
|
||||
brig_to_generic::get_brig_operand_entry (size_t entry_offset) const
|
||||
{
|
||||
return (const BrigBase *) (m_operand + entry_offset);
|
||||
}
|
||||
|
||||
const BrigBase *
|
||||
brig_to_generic::get_brig_code_entry (size_t entry_offset) const
|
||||
{
|
||||
return (const BrigBase *) (m_code + entry_offset);
|
||||
}
|
||||
|
||||
void
|
||||
brig_to_generic::append_global (tree g)
|
||||
{
|
||||
if (m_globals == NULL_TREE)
|
||||
{
|
||||
m_globals = g;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree last = tree_last (m_globals);
|
||||
TREE_CHAIN (last) = g;
|
||||
}
|
||||
}
|
||||
|
||||
tree
|
||||
brig_to_generic::global_variable (const std::string &name) const
|
||||
{
|
||||
label_index::const_iterator i = m_global_variables.find (name);
|
||||
if (i == m_global_variables.end ())
|
||||
return NULL_TREE;
|
||||
else
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
/* Returns a function declaration with the given name. Assumes it has been
|
||||
created previously via a DirectiveFunction or similar. */
|
||||
|
||||
tree
|
||||
brig_to_generic::function_decl (const std::string &name)
|
||||
{
|
||||
label_index::const_iterator i = m_function_index.find (name);
|
||||
if (i == m_function_index.end ())
|
||||
return NULL_TREE;
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
void
|
||||
brig_to_generic::add_function_decl (const std::string &name, tree func_decl)
|
||||
{
|
||||
m_function_index[name] = func_decl;
|
||||
}
|
||||
|
||||
/* Adds a GENERIC global variable VAR_DECL with the given NAME to the
|
||||
current module. If we have generated a host def var ptr (a place holder
|
||||
for variables that are defined by the HSA host code) for this global
|
||||
variable definition (because there was a declaration earlier which looked
|
||||
like it might have been a host defined variable), we now have
|
||||
to assign its address and make it private to allow the references to
|
||||
point to the defined variable instead. */
|
||||
|
||||
void
|
||||
brig_to_generic::add_global_variable (const std::string &name, tree var_decl)
|
||||
{
|
||||
append_global (var_decl);
|
||||
m_global_variables[name] = var_decl;
|
||||
|
||||
std::string host_def_var_name
|
||||
= std::string (PHSA_HOST_DEF_PTR_PREFIX) + name;
|
||||
tree host_def_var = global_variable (host_def_var_name.c_str ());
|
||||
if (host_def_var == NULL_TREE)
|
||||
return;
|
||||
|
||||
tree ptype = build_pointer_type (TREE_TYPE (var_decl));
|
||||
tree var_addr = build1 (ADDR_EXPR, ptype, var_decl);
|
||||
|
||||
DECL_INITIAL (host_def_var) = var_addr;
|
||||
TREE_PUBLIC (host_def_var) = 0;
|
||||
}
|
||||
|
||||
/* Adds an indirection pointer for a potential host-defined program scope
|
||||
variable declaration. */
|
||||
|
||||
void
|
||||
brig_to_generic::add_host_def_var_ptr (const std::string &name, tree var_decl)
|
||||
{
|
||||
std::string var_name = std::string (PHSA_HOST_DEF_PTR_PREFIX) + name;
|
||||
|
||||
tree name_identifier = get_identifier (var_name.c_str ());
|
||||
|
||||
tree ptr_var = build_decl (UNKNOWN_LOCATION, VAR_DECL, name_identifier,
|
||||
build_pointer_type (TREE_TYPE (var_decl)));
|
||||
DECL_EXTERNAL (ptr_var) = 0;
|
||||
DECL_ARTIFICIAL (ptr_var) = 0;
|
||||
|
||||
TREE_PUBLIC (ptr_var) = 1;
|
||||
TREE_USED (ptr_var) = 1;
|
||||
TREE_ADDRESSABLE (ptr_var) = 1;
|
||||
TREE_STATIC (ptr_var) = 1;
|
||||
|
||||
append_global (ptr_var);
|
||||
m_global_variables[var_name] = ptr_var;
|
||||
}
|
||||
|
||||
/* Produce a "mangled name" for the given brig function or kernel.
|
||||
The mangling is used to make unique global symbol name in case of
|
||||
module scope functions. Program scope functions are not mangled
|
||||
(except for dropping the leading &), which makes the functions
|
||||
directly visible for linking using the original function name. */
|
||||
|
||||
std::string
|
||||
brig_to_generic::get_mangled_name
|
||||
(const BrigDirectiveExecutable *func) const
|
||||
{
|
||||
/* Strip the leading &. */
|
||||
std::string func_name = get_string (func->name).substr (1);
|
||||
if (func->linkage == BRIG_LINKAGE_MODULE)
|
||||
{
|
||||
/* Mangle the module scope function names with the module name and
|
||||
make them public so they can be queried by the HSA runtime from
|
||||
the produced binary. Assume it's the currently processed function
|
||||
we are always referring to. */
|
||||
func_name = "gccbrig." + m_module_name + "." + func_name;
|
||||
}
|
||||
return func_name;
|
||||
}
|
||||
|
||||
std::string
|
||||
brig_to_generic::get_string (size_t entry_offset) const
|
||||
{
|
||||
const BrigData *data_item = get_brig_data_entry (entry_offset);
|
||||
return std::string ((const char *) &data_item->bytes, data_item->byteCount);
|
||||
}
|
||||
|
||||
/* Adapted from c-semantics.c. */
|
||||
|
||||
tree
|
||||
build_stmt (enum tree_code code, ...)
|
||||
{
|
||||
tree ret;
|
||||
int length, i;
|
||||
va_list p;
|
||||
bool side_effects;
|
||||
|
||||
/* This function cannot be used to construct variably-sized nodes. */
|
||||
gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);
|
||||
|
||||
va_start (p, code);
|
||||
|
||||
ret = make_node (code);
|
||||
TREE_TYPE (ret) = void_type_node;
|
||||
length = TREE_CODE_LENGTH (code);
|
||||
|
||||
/* TREE_SIDE_EFFECTS will already be set for statements with
|
||||
implicit side effects. Here we make sure it is set for other
|
||||
expressions by checking whether the parameters have side
|
||||
effects. */
|
||||
|
||||
side_effects = false;
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
tree t = va_arg (p, tree);
|
||||
if (t && !TYPE_P (t))
|
||||
side_effects |= TREE_SIDE_EFFECTS (t);
|
||||
TREE_OPERAND (ret, i) = t;
|
||||
}
|
||||
|
||||
TREE_SIDE_EFFECTS (ret) |= side_effects;
|
||||
|
||||
va_end (p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* BRIG regs are untyped, but GENERIC is not. We need to add implicit casts
|
||||
in case treating the operand with an instruction with a type different
|
||||
than the created reg var type in order to select correct instruction type
|
||||
later on. This function creates the necessary reinterpret type cast from
|
||||
a source variable to the destination type. In case no cast is needed to
|
||||
the same type, SOURCE is returned directly. */
|
||||
|
||||
tree
|
||||
build_reinterpret_cast (tree destination_type, tree source)
|
||||
{
|
||||
|
||||
gcc_assert (source && destination_type && TREE_TYPE (source) != NULL_TREE
|
||||
&& destination_type != NULL_TREE);
|
||||
|
||||
tree source_type = TREE_TYPE (source);
|
||||
if (TREE_CODE (source) == CALL_EXPR)
|
||||
{
|
||||
tree func_decl = TREE_OPERAND (TREE_OPERAND (source, 1), 0);
|
||||
source_type = TREE_TYPE (TREE_TYPE (func_decl));
|
||||
}
|
||||
|
||||
if (destination_type == source_type)
|
||||
return source;
|
||||
|
||||
size_t src_size = int_size_in_bytes (source_type);
|
||||
size_t dst_size = int_size_in_bytes (destination_type);
|
||||
if (src_size == dst_size)
|
||||
return build1 (VIEW_CONVERT_EXPR, destination_type, source);
|
||||
else if (src_size < dst_size)
|
||||
{
|
||||
/* The src_size can be smaller at least with f16 scalars which are
|
||||
stored to 32b register variables. First convert to an equivalent
|
||||
size unsigned type, then extend to an unsigned type of the
|
||||
target width, after which VIEW_CONVERT_EXPR can be used to
|
||||
force to the target type. */
|
||||
tree unsigned_temp = build1 (VIEW_CONVERT_EXPR,
|
||||
get_unsigned_int_type (source_type),
|
||||
source);
|
||||
return build1 (VIEW_CONVERT_EXPR, destination_type,
|
||||
convert (get_unsigned_int_type (destination_type),
|
||||
unsigned_temp));
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Returns the finished brig_function for the given generic FUNC_DECL,
|
||||
or NULL, if not found. */
|
||||
|
||||
brig_function *
|
||||
brig_to_generic::get_finished_function (tree func_decl)
|
||||
{
|
||||
std::string func_name
|
||||
= identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (func_decl)));
|
||||
std::map<std::string, brig_function *>::iterator i
|
||||
= m_finished_functions.find (func_name);
|
||||
if (i != m_finished_functions.end ())
|
||||
return (*i).second;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Finalizes the currently handled function. Should be called before
|
||||
setting a new function. */
|
||||
|
||||
void
|
||||
brig_to_generic::finish_function ()
|
||||
{
|
||||
if (m_cf == NULL || m_cf->m_func_decl == NULL_TREE)
|
||||
{
|
||||
/* It can be a finished func declaration fingerprint, in that case we
|
||||
don't have m_func_decl. */
|
||||
m_cf = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_cf->m_is_kernel)
|
||||
{
|
||||
tree bind_expr = m_cf->m_current_bind_expr;
|
||||
tree stmts = BIND_EXPR_BODY (bind_expr);
|
||||
m_cf->finish ();
|
||||
m_cf->emit_metadata (stmts);
|
||||
dump_function (m_dump_file, m_cf);
|
||||
gimplify_function_tree (m_cf->m_func_decl);
|
||||
cgraph_node::finalize_function (m_cf->m_func_decl, true);
|
||||
}
|
||||
else
|
||||
/* Emit the kernel only at the very end so we can analyze the total
|
||||
group and private memory usage. */
|
||||
m_kernels.push_back (m_cf);
|
||||
|
||||
pop_cfun ();
|
||||
|
||||
m_finished_functions[m_cf->m_name] = m_cf;
|
||||
m_cf = NULL;
|
||||
}
|
||||
|
||||
/* Initializes a new currently handled function. */
|
||||
|
||||
void
|
||||
brig_to_generic::start_function (tree f)
|
||||
{
|
||||
if (DECL_STRUCT_FUNCTION (f) == NULL)
|
||||
push_struct_function (f);
|
||||
else
|
||||
push_cfun (DECL_STRUCT_FUNCTION (f));
|
||||
|
||||
m_cf->m_func_decl = f;
|
||||
}
|
||||
|
||||
/* Appends a new group variable (or an fbarrier) to the current kernel's
|
||||
group segment. */
|
||||
|
||||
void
|
||||
brig_to_generic::append_group_variable (const std::string &name, size_t size,
|
||||
size_t alignment)
|
||||
{
|
||||
size_t align_padding = m_next_group_offset % alignment == 0 ?
|
||||
0 : (alignment - m_next_group_offset % alignment);
|
||||
m_next_group_offset += align_padding;
|
||||
m_group_offsets[name] = m_next_group_offset;
|
||||
m_next_group_offset += size;
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_to_generic::group_variable_segment_offset (const std::string &name) const
|
||||
{
|
||||
var_offset_table::const_iterator i = m_group_offsets.find (name);
|
||||
gcc_assert (i != m_group_offsets.end ());
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
/* The size of the group and private segments required by the currently
|
||||
processed kernel. Private segment size must be multiplied by the
|
||||
number of work-items in the launch, in case of a work-group function. */
|
||||
|
||||
size_t
|
||||
brig_to_generic::group_segment_size () const
|
||||
{
|
||||
return m_next_group_offset;
|
||||
}
|
||||
|
||||
/* Appends a new group variable to the current kernel's private segment. */
|
||||
|
||||
void
|
||||
brig_to_generic::append_private_variable (const std::string &name,
|
||||
size_t size, size_t alignment)
|
||||
{
|
||||
size_t align_padding = m_next_private_offset % alignment == 0 ?
|
||||
0 : (alignment - m_next_private_offset % alignment);
|
||||
m_next_private_offset += align_padding;
|
||||
m_private_offsets[name] = m_next_private_offset;
|
||||
m_next_private_offset += size;
|
||||
m_private_data_sizes[name] = size + align_padding;
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_to_generic::private_variable_segment_offset
|
||||
(const std::string &name) const
|
||||
{
|
||||
var_offset_table::const_iterator i = m_private_offsets.find (name);
|
||||
gcc_assert (i != m_private_offsets.end ());
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
bool
|
||||
brig_to_generic::has_private_variable (const std::string &name) const
|
||||
{
|
||||
std::map<std::string, size_t>::const_iterator i
|
||||
= m_private_data_sizes.find (name);
|
||||
return i != m_private_data_sizes.end ();
|
||||
}
|
||||
|
||||
bool
|
||||
brig_to_generic::has_group_variable (const std::string &name) const
|
||||
{
|
||||
var_offset_table::const_iterator i = m_group_offsets.find (name);
|
||||
return i != m_group_offsets.end ();
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_to_generic::private_variable_size (const std::string &name) const
|
||||
{
|
||||
std::map<std::string, size_t>::const_iterator i
|
||||
= m_private_data_sizes.find (name);
|
||||
gcc_assert (i != m_private_data_sizes.end ());
|
||||
return (*i).second;
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_to_generic::private_segment_size () const
|
||||
{
|
||||
return m_next_private_offset;
|
||||
}
|
||||
|
||||
/* Cached builtins indexed by name. */
|
||||
|
||||
typedef std::map<std::string, tree> builtin_index;
|
||||
builtin_index builtin_cache_;
|
||||
|
||||
/* Build a call to a builtin function. PDECL is the builtin function to
|
||||
call. NARGS is the number of input arguments, RETTYPE the built-in
|
||||
functions return value type, and ... is the list of arguments passed to
|
||||
the call with type first, then the value. */
|
||||
|
||||
tree
|
||||
call_builtin (tree pdecl, int nargs, tree rettype, ...)
|
||||
{
|
||||
if (rettype == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
tree *types = new tree[nargs];
|
||||
tree *args = new tree[nargs];
|
||||
|
||||
va_list ap;
|
||||
va_start (ap, rettype);
|
||||
for (int i = 0; i < nargs; ++i)
|
||||
{
|
||||
types[i] = va_arg (ap, tree);
|
||||
tree arg = va_arg (ap, tree);
|
||||
args[i] = build_reinterpret_cast (types[i], arg);
|
||||
if (types[i] == error_mark_node || args[i] == error_mark_node)
|
||||
{
|
||||
delete[] types;
|
||||
delete[] args;
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
tree fnptr = build_fold_addr_expr (pdecl);
|
||||
|
||||
tree ret = build_call_array (rettype, fnptr, nargs, args);
|
||||
|
||||
delete[] types;
|
||||
delete[] args;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Generate all global declarations. Should be called after the last
|
||||
BRIG has been fed in. */
|
||||
|
||||
void
|
||||
brig_to_generic::write_globals ()
|
||||
{
|
||||
/* Now that the whole BRIG module has been processed, build a launcher
|
||||
and a metadata section for each built kernel. */
|
||||
for (size_t i = 0; i < m_kernels.size (); ++i)
|
||||
{
|
||||
brig_function *f = m_kernels[i];
|
||||
|
||||
/* Finish kernels now that we know the call graphs and their barrier
|
||||
usage. */
|
||||
f->finish_kernel ();
|
||||
|
||||
dump_function (m_dump_file, f);
|
||||
gimplify_function_tree (f->m_func_decl);
|
||||
cgraph_node::finalize_function (f->m_func_decl, true);
|
||||
|
||||
f->m_descriptor.is_kernel = 1;
|
||||
/* TODO: analyze the kernel's actual group and private segment usage
|
||||
using a call graph. Now the private and group mem sizes are overly
|
||||
pessimistic in case of multiple kernels in the same module. */
|
||||
f->m_descriptor.group_segment_size = group_segment_size ();
|
||||
f->m_descriptor.private_segment_size = private_segment_size ();
|
||||
|
||||
/* The kernarg size is rounded up to a multiple of 16 according to
|
||||
the PRM specs. */
|
||||
f->m_descriptor.kernarg_segment_size = f->m_next_kernarg_offset;
|
||||
if (f->m_descriptor.kernarg_segment_size % 16 > 0)
|
||||
f->m_descriptor.kernarg_segment_size
|
||||
+= 16 - f->m_next_kernarg_offset % 16;
|
||||
f->m_descriptor.kernarg_max_align = f->m_kernarg_max_align;
|
||||
|
||||
tree launcher = f->emit_launcher_and_metadata ();
|
||||
|
||||
append_global (launcher);
|
||||
|
||||
gimplify_function_tree (launcher);
|
||||
cgraph_node::finalize_function (launcher, true);
|
||||
pop_cfun ();
|
||||
}
|
||||
|
||||
int no_globals = list_length (m_globals);
|
||||
tree *vec = new tree[no_globals];
|
||||
|
||||
int i = 0;
|
||||
tree global = m_globals;
|
||||
while (global)
|
||||
{
|
||||
vec[i] = global;
|
||||
++i;
|
||||
global = TREE_CHAIN (global);
|
||||
}
|
||||
|
||||
wrapup_global_declarations (vec, no_globals);
|
||||
|
||||
delete[] vec;
|
||||
|
||||
for (size_t i = 0; i < m_brig_blobs.size (); ++i)
|
||||
delete m_brig_blobs[i];
|
||||
}
|
||||
|
||||
/* Returns an type with unsigned int elements corresponding to the
|
||||
size and element count of ORIGINAL_TYPE. */
|
||||
|
||||
tree
|
||||
get_unsigned_int_type (tree original_type)
|
||||
{
|
||||
if (VECTOR_TYPE_P (original_type))
|
||||
{
|
||||
size_t esize
|
||||
= int_size_in_bytes (TREE_TYPE (original_type)) * BITS_PER_UNIT;
|
||||
size_t ecount = TYPE_VECTOR_SUBPARTS (original_type);
|
||||
return build_vector_type (build_nonstandard_integer_type (esize, true),
|
||||
ecount);
|
||||
}
|
||||
else
|
||||
return build_nonstandard_integer_type (int_size_in_bytes (original_type)
|
||||
* BITS_PER_UNIT,
|
||||
true);
|
||||
}
|
||||
|
||||
void
|
||||
dump_function (FILE *dump_file, brig_function *f)
|
||||
{
|
||||
/* Dump the BRIG-specific tree IR. */
|
||||
if (dump_file)
|
||||
{
|
||||
fprintf (dump_file, "\n;; Function %s", f->m_name.c_str ());
|
||||
fprintf (dump_file, "\n;; enabled by -%s\n\n",
|
||||
dump_flag_name (TDI_original));
|
||||
print_generic_decl (dump_file, f->m_func_decl, 0);
|
||||
print_generic_expr (dump_file, f->m_current_bind_expr, 0);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
}
|
225
gcc/brig/brigfrontend/brig-to-generic.h
Normal file
225
gcc/brig/brigfrontend/brig-to-generic.h
Normal file
|
@ -0,0 +1,225 @@
|
|||
/* brig-to-generic.h -- brig to gcc generic conversion
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef BRIG_TO_GENERIC_H
|
||||
#define BRIG_TO_GENERIC_H
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "ansidecl.h"
|
||||
#include "coretypes.h"
|
||||
#include "opts.h"
|
||||
#include "tree.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "hsa-brig-format.h"
|
||||
#include "brig-function.h"
|
||||
|
||||
|
||||
struct reg_decl_index_entry;
|
||||
|
||||
/* Converts an HSAIL BRIG input to GENERIC. This class holds global state
|
||||
for the translation process. Handling of the smaller pieces of BRIG data
|
||||
is delegated to various handler classes declared in
|
||||
brig-code-entry-handlers.h. */
|
||||
|
||||
class brig_to_generic
|
||||
{
|
||||
public:
|
||||
typedef std::map<const BrigDirectiveVariable *, tree> variable_index;
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, size_t> var_offset_table;
|
||||
typedef std::map<const BrigBase *, std::string> name_index;
|
||||
|
||||
public:
|
||||
brig_to_generic ();
|
||||
|
||||
void parse (const char *brig_blob);
|
||||
|
||||
void write_globals ();
|
||||
|
||||
std::string get_string (size_t entry_offset) const;
|
||||
|
||||
const BrigData *get_brig_data_entry (size_t entry_offset) const;
|
||||
const BrigBase *get_brig_operand_entry (size_t entry_offset) const;
|
||||
const BrigBase *get_brig_code_entry (size_t entry_offset) const;
|
||||
|
||||
void append_global (tree g);
|
||||
|
||||
tree function_decl (const std::string &name);
|
||||
void add_function_decl (const std::string &name, tree func_decl);
|
||||
|
||||
tree global_variable (const std::string &name) const;
|
||||
void add_global_variable (const std::string &name, tree var_decl);
|
||||
void add_host_def_var_ptr (const std::string &name, tree var_decl);
|
||||
|
||||
void start_function (tree f);
|
||||
void finish_function ();
|
||||
|
||||
void append_group_variable (const std::string &name, size_t size,
|
||||
size_t alignment);
|
||||
|
||||
void append_private_variable (const std::string &name, size_t size,
|
||||
size_t alignment);
|
||||
|
||||
size_t group_variable_segment_offset (const std::string &name) const;
|
||||
|
||||
bool
|
||||
has_group_variable (const std::string &name) const;
|
||||
|
||||
size_t
|
||||
private_variable_segment_offset (const std::string &name) const;
|
||||
|
||||
bool
|
||||
has_private_variable (const std::string &name) const;
|
||||
|
||||
size_t private_variable_size (const std::string &name) const;
|
||||
|
||||
template <typename T>
|
||||
std::string
|
||||
get_mangled_name_tmpl (const T *brigVar) const;
|
||||
|
||||
std::string get_mangled_name (const BrigDirectiveFbarrier *fbar) const
|
||||
{ return get_mangled_name_tmpl (fbar); }
|
||||
std::string get_mangled_name (const BrigDirectiveVariable *var) const
|
||||
{ return get_mangled_name_tmpl (var); }
|
||||
std::string get_mangled_name (const BrigDirectiveExecutable *func) const;
|
||||
|
||||
size_t group_segment_size () const;
|
||||
size_t private_segment_size () const;
|
||||
|
||||
brig_function *get_finished_function (tree func_decl);
|
||||
|
||||
static tree s_fp16_type;
|
||||
static tree s_fp32_type;
|
||||
static tree s_fp64_type;
|
||||
|
||||
/* The default rounding mode that should be used for float instructions.
|
||||
This can be set in each BRIG module header. */
|
||||
BrigRound8_t m_default_float_rounding_mode;
|
||||
|
||||
/* The currently built function. */
|
||||
brig_function *m_cf;
|
||||
|
||||
/* The name of the currently handled BRIG module. */
|
||||
std::string m_module_name;
|
||||
|
||||
private:
|
||||
/* The BRIG blob and its different sections of the file currently being
|
||||
parsed. */
|
||||
const char *m_brig;
|
||||
const char *m_data;
|
||||
size_t m_data_size;
|
||||
const char *m_operand;
|
||||
size_t m_operand_size;
|
||||
const char *m_code;
|
||||
size_t m_code_size;
|
||||
|
||||
tree m_globals;
|
||||
|
||||
label_index m_global_variables;
|
||||
|
||||
/* The size of each private variable, including the alignment padding. */
|
||||
std::map<std::string, size_t> m_private_data_sizes;
|
||||
|
||||
/* The same for group variables. */
|
||||
size_t m_next_group_offset;
|
||||
var_offset_table m_group_offsets;
|
||||
|
||||
/* And private. */
|
||||
size_t m_next_private_offset;
|
||||
var_offset_table m_private_offsets;
|
||||
|
||||
/* Name index for declared functions. */
|
||||
label_index m_function_index;
|
||||
|
||||
/* Stores all processed kernels in order. */
|
||||
std::vector<brig_function *> m_kernels;
|
||||
|
||||
/* Stores all already processed functions from the translation unit
|
||||
for some interprocedural analysis. */
|
||||
std::map<std::string, brig_function *> m_finished_functions;
|
||||
|
||||
/* The parsed BRIG blobs. Owned and will be deleted after use. */
|
||||
std::vector<const char *> m_brig_blobs;
|
||||
|
||||
/* The original dump file. */
|
||||
FILE *m_dump_file;
|
||||
|
||||
/* The original dump file flags. */
|
||||
int m_dump_flags;
|
||||
};
|
||||
|
||||
/* Produce a "mangled name" for the given brig variable. The mangling is used
|
||||
to make unique global symbol names for module and function scope variables.
|
||||
The templated version is suitable for most of the variable types. Functions
|
||||
and kernels (BrigDirectiveExecutable) are handled with a specialized
|
||||
get_mangled_name() version. */
|
||||
|
||||
template <typename T>
|
||||
std::string
|
||||
brig_to_generic::get_mangled_name_tmpl (const T *brigVar) const
|
||||
{
|
||||
std::string var_name = get_string (brigVar->name).substr (1);
|
||||
|
||||
/* Mangle the variable name using the function name and the module name
|
||||
in case of a function scope variable. */
|
||||
if (m_cf != NULL
|
||||
&& m_cf->has_function_scope_var (&brigVar->base))
|
||||
var_name = m_cf->m_name + "." + var_name;
|
||||
|
||||
if (brigVar->linkage == BRIG_LINKAGE_MODULE)
|
||||
var_name = "gccbrig." + m_module_name + "." + var_name;
|
||||
return var_name;
|
||||
}
|
||||
|
||||
/* An interface to organize the different types of BRIG element handlers. */
|
||||
|
||||
class brig_entry_handler
|
||||
{
|
||||
public:
|
||||
brig_entry_handler (brig_to_generic &parent) : m_parent (parent)
|
||||
{
|
||||
}
|
||||
|
||||
/* Handles the brig_code data at the given pointer and adds it to the
|
||||
currently built tree. Returns the number of consumed bytes; */
|
||||
virtual size_t operator () (const BrigBase *base) = 0;
|
||||
|
||||
protected:
|
||||
brig_to_generic &m_parent;
|
||||
};
|
||||
|
||||
tree call_builtin (tree pdecl, int nargs, tree rettype, ...);
|
||||
|
||||
tree build_reinterpret_cast (tree destination_type, tree source);
|
||||
|
||||
tree build_stmt (enum tree_code code, ...);
|
||||
|
||||
tree get_unsigned_int_type (tree type);
|
||||
|
||||
void dump_function (FILE *dump_file, brig_function *f);
|
||||
|
||||
#endif
|
447
gcc/brig/brigfrontend/brig-util.cc
Normal file
447
gcc/brig/brigfrontend/brig-util.cc
Normal file
|
@ -0,0 +1,447 @@
|
|||
/* brig-util.cc -- gccbrig utility functions
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "stdint.h"
|
||||
#include "hsa-brig-format.h"
|
||||
#include "brig-util.h"
|
||||
#include "errors.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
/* Return true if operand number OPNUM of instruction with OPCODE is an output.
|
||||
False if it is an input. Some code reused from Martin Jambor's gcc-hsa
|
||||
tree. */
|
||||
|
||||
bool
|
||||
gccbrig_hsa_opcode_op_output_p (BrigOpcode16_t opcode, int opnum)
|
||||
{
|
||||
switch (opcode)
|
||||
{
|
||||
case BRIG_OPCODE_BR:
|
||||
case BRIG_OPCODE_SBR:
|
||||
case BRIG_OPCODE_CBR:
|
||||
case BRIG_OPCODE_ST:
|
||||
case BRIG_OPCODE_ATOMICNORET:
|
||||
case BRIG_OPCODE_SIGNALNORET:
|
||||
case BRIG_OPCODE_INITFBAR:
|
||||
case BRIG_OPCODE_JOINFBAR:
|
||||
case BRIG_OPCODE_WAITFBAR:
|
||||
case BRIG_OPCODE_ARRIVEFBAR:
|
||||
case BRIG_OPCODE_LEAVEFBAR:
|
||||
case BRIG_OPCODE_RELEASEFBAR:
|
||||
case BRIG_OPCODE_DEBUGTRAP:
|
||||
return false;
|
||||
default:
|
||||
return opnum == 0;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned
|
||||
gccbrig_hsa_type_bit_size (BrigType16_t t)
|
||||
{
|
||||
|
||||
unsigned pack_type = t & ~BRIG_TYPE_BASE_MASK;
|
||||
|
||||
if (pack_type == BRIG_TYPE_PACK_32)
|
||||
return 32;
|
||||
else if (pack_type == BRIG_TYPE_PACK_64)
|
||||
return 64;
|
||||
else if (pack_type == BRIG_TYPE_PACK_128)
|
||||
return 128;
|
||||
|
||||
switch (t)
|
||||
{
|
||||
case BRIG_TYPE_NONE:
|
||||
return 0;
|
||||
|
||||
case BRIG_TYPE_B1:
|
||||
return 1;
|
||||
|
||||
case BRIG_TYPE_U8:
|
||||
case BRIG_TYPE_S8:
|
||||
case BRIG_TYPE_B8:
|
||||
return 8;
|
||||
|
||||
case BRIG_TYPE_U16:
|
||||
case BRIG_TYPE_S16:
|
||||
case BRIG_TYPE_B16:
|
||||
case BRIG_TYPE_F16:
|
||||
return 16;
|
||||
|
||||
case BRIG_TYPE_U32:
|
||||
case BRIG_TYPE_S32:
|
||||
case BRIG_TYPE_B32:
|
||||
case BRIG_TYPE_F32:
|
||||
case BRIG_TYPE_U8X4:
|
||||
case BRIG_TYPE_U16X2:
|
||||
case BRIG_TYPE_S8X4:
|
||||
case BRIG_TYPE_S16X2:
|
||||
case BRIG_TYPE_F16X2:
|
||||
case BRIG_TYPE_SIG32:
|
||||
return 32;
|
||||
|
||||
case BRIG_TYPE_U64:
|
||||
case BRIG_TYPE_S64:
|
||||
case BRIG_TYPE_F64:
|
||||
case BRIG_TYPE_B64:
|
||||
case BRIG_TYPE_U8X8:
|
||||
case BRIG_TYPE_U16X4:
|
||||
case BRIG_TYPE_U32X2:
|
||||
case BRIG_TYPE_S8X8:
|
||||
case BRIG_TYPE_S16X4:
|
||||
case BRIG_TYPE_S32X2:
|
||||
case BRIG_TYPE_F16X4:
|
||||
case BRIG_TYPE_F32X2:
|
||||
case BRIG_TYPE_SIG64:
|
||||
return 64;
|
||||
|
||||
case BRIG_TYPE_B128:
|
||||
case BRIG_TYPE_U8X16:
|
||||
case BRIG_TYPE_U16X8:
|
||||
case BRIG_TYPE_U32X4:
|
||||
case BRIG_TYPE_U64X2:
|
||||
case BRIG_TYPE_S8X16:
|
||||
case BRIG_TYPE_S16X8:
|
||||
case BRIG_TYPE_S32X4:
|
||||
case BRIG_TYPE_S64X2:
|
||||
case BRIG_TYPE_F16X8:
|
||||
case BRIG_TYPE_F32X4:
|
||||
case BRIG_TYPE_F64X2:
|
||||
return 128;
|
||||
|
||||
default:
|
||||
printf ("HMM %d %x\n", t, t);
|
||||
gcc_unreachable ();
|
||||
}
|
||||
}
|
||||
|
||||
/* gcc-hsa borrowed code ENDS. */
|
||||
|
||||
uint64_t
|
||||
gccbrig_to_uint64_t (const BrigUInt64 &brig_type)
|
||||
{
|
||||
return (uint64_t (brig_type.hi) << 32) | uint64_t (brig_type.lo);
|
||||
}
|
||||
|
||||
int
|
||||
gccbrig_reg_size (const BrigOperandRegister *brig_reg)
|
||||
{
|
||||
switch (brig_reg->regKind)
|
||||
{
|
||||
case BRIG_REGISTER_KIND_CONTROL:
|
||||
return 1;
|
||||
case BRIG_REGISTER_KIND_SINGLE:
|
||||
return 32;
|
||||
case BRIG_REGISTER_KIND_DOUBLE:
|
||||
return 64;
|
||||
case BRIG_REGISTER_KIND_QUAD:
|
||||
return 128;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
gccbrig_reg_name (const BrigOperandRegister *reg)
|
||||
{
|
||||
std::ostringstream strstr;
|
||||
switch (reg->regKind)
|
||||
{
|
||||
case BRIG_REGISTER_KIND_CONTROL:
|
||||
strstr << 'c';
|
||||
break;
|
||||
case BRIG_REGISTER_KIND_SINGLE:
|
||||
strstr << 's';
|
||||
break;
|
||||
case BRIG_REGISTER_KIND_DOUBLE:
|
||||
strstr << 'd';
|
||||
break;
|
||||
case BRIG_REGISTER_KIND_QUAD:
|
||||
strstr << 'q';
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
return "";
|
||||
}
|
||||
strstr << reg->regNum;
|
||||
return strstr.str ();
|
||||
}
|
||||
|
||||
std::string
|
||||
gccbrig_type_name (BrigType16_t type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case BRIG_TYPE_U8:
|
||||
return "u8";
|
||||
case BRIG_TYPE_U16:
|
||||
return "u16";
|
||||
case BRIG_TYPE_U32:
|
||||
return "u32";
|
||||
case BRIG_TYPE_U64:
|
||||
return "u64";
|
||||
case BRIG_TYPE_S8:
|
||||
return "s8";
|
||||
case BRIG_TYPE_S16:
|
||||
return "s16";
|
||||
case BRIG_TYPE_S32:
|
||||
return "s32";
|
||||
case BRIG_TYPE_S64:
|
||||
return "s64";
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
gccbrig_segment_name (BrigSegment8_t segment)
|
||||
{
|
||||
if (segment == BRIG_SEGMENT_GLOBAL)
|
||||
return "global";
|
||||
else if (segment == BRIG_SEGMENT_GROUP)
|
||||
return "group";
|
||||
else if (segment == BRIG_SEGMENT_PRIVATE)
|
||||
return "private";
|
||||
else
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
bool
|
||||
gccbrig_is_float_type (BrigType16_t type)
|
||||
{
|
||||
return (type == BRIG_TYPE_F32 || type == BRIG_TYPE_F64
|
||||
|| type == BRIG_TYPE_F16);
|
||||
}
|
||||
|
||||
BrigType16_t
|
||||
gccbrig_tree_type_to_hsa_type (tree tree_type)
|
||||
{
|
||||
if (INTEGRAL_TYPE_P (tree_type))
|
||||
{
|
||||
if (TYPE_UNSIGNED (tree_type))
|
||||
{
|
||||
switch (int_size_in_bytes (tree_type))
|
||||
{
|
||||
case 1:
|
||||
return BRIG_TYPE_U8;
|
||||
case 2:
|
||||
return BRIG_TYPE_U16;
|
||||
case 4:
|
||||
return BRIG_TYPE_U32;
|
||||
case 8:
|
||||
return BRIG_TYPE_U64;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (int_size_in_bytes (tree_type))
|
||||
{
|
||||
case 1:
|
||||
return BRIG_TYPE_S8;
|
||||
case 2:
|
||||
return BRIG_TYPE_S16;
|
||||
case 4:
|
||||
return BRIG_TYPE_S32;
|
||||
case 8:
|
||||
return BRIG_TYPE_S64;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (VECTOR_TYPE_P (tree_type))
|
||||
{
|
||||
tree element_type = TREE_TYPE (tree_type);
|
||||
size_t element_size = int_size_in_bytes (element_type) * 8;
|
||||
BrigType16_t brig_element_type;
|
||||
switch (element_size)
|
||||
{
|
||||
case 8:
|
||||
brig_element_type
|
||||
= TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U8 : BRIG_TYPE_S8;
|
||||
break;
|
||||
case 16:
|
||||
brig_element_type
|
||||
= TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U16 : BRIG_TYPE_S16;
|
||||
break;
|
||||
case 32:
|
||||
brig_element_type
|
||||
= TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U32 : BRIG_TYPE_S32;
|
||||
break;
|
||||
case 64:
|
||||
brig_element_type
|
||||
= TYPE_UNSIGNED (element_type) ? BRIG_TYPE_U64 : BRIG_TYPE_S64;
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
BrigType16_t pack_type;
|
||||
switch (int_size_in_bytes (tree_type) * 8)
|
||||
{
|
||||
case 32:
|
||||
pack_type = BRIG_TYPE_PACK_32;
|
||||
break;
|
||||
case 64:
|
||||
pack_type = BRIG_TYPE_PACK_64;
|
||||
break;
|
||||
case 128:
|
||||
pack_type = BRIG_TYPE_PACK_128;
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
return brig_element_type | pack_type;
|
||||
}
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* Returns true in case the operation is a "bit level" operation,
|
||||
that is, not having operand type depending semantical differences. */
|
||||
|
||||
bool
|
||||
gccbrig_is_bit_operation (BrigOpcode16_t opcode)
|
||||
{
|
||||
return opcode == BRIG_OPCODE_CMOV || opcode == BRIG_OPCODE_SHUFFLE
|
||||
|| opcode == BRIG_OPCODE_UNPACK || opcode == BRIG_OPCODE_UNPACKLO
|
||||
|| opcode == BRIG_OPCODE_UNPACKHI || opcode == BRIG_OPCODE_ST
|
||||
|| opcode == BRIG_OPCODE_PACK;
|
||||
}
|
||||
|
||||
/* The program scope definition can be left external within the
|
||||
kernel binary which means it must be defined by the host via
|
||||
HSA runtime. For these we have special treatment:
|
||||
Create additional pointer indirection when accessing the variable
|
||||
value from kernel code through a generated pointer
|
||||
__gccbrig_ptr_variable_name. The pointer value then can be set either
|
||||
within the kernel binary (in case of a later linked in definition)
|
||||
or from the host. */
|
||||
|
||||
bool
|
||||
gccbrig_might_be_host_defined_var_p (const BrigDirectiveVariable *brigVar)
|
||||
{
|
||||
bool is_definition = brigVar->modifier & BRIG_VARIABLE_DEFINITION;
|
||||
return (brigVar->segment == BRIG_SEGMENT_GLOBAL
|
||||
|| brigVar->segment == BRIG_SEGMENT_READONLY) && !is_definition
|
||||
&& brigVar->linkage == BRIG_LINKAGE_PROGRAM
|
||||
&& (brigVar->allocation == BRIG_ALLOCATION_PROGRAM
|
||||
|| brigVar->allocation == BRIG_ALLOCATION_AGENT);
|
||||
}
|
||||
|
||||
/* Produce a GENERIC type for the given HSA/BRIG type. Returns the element
|
||||
type in case of vector instructions. */
|
||||
|
||||
tree
|
||||
gccbrig_tree_type_for_hsa_type (BrigType16_t brig_type)
|
||||
{
|
||||
tree tree_type = NULL_TREE;
|
||||
|
||||
if (hsa_type_packed_p (brig_type))
|
||||
{
|
||||
/* The element type is encoded in the bottom 5 bits. */
|
||||
BrigType16_t inner_brig_type = brig_type & BRIG_TYPE_BASE_MASK;
|
||||
|
||||
unsigned full_size = gccbrig_hsa_type_bit_size (brig_type);
|
||||
|
||||
if (inner_brig_type == BRIG_TYPE_F16)
|
||||
return build_vector_type (gccbrig_tree_type_for_hsa_type (BRIG_TYPE_U16),
|
||||
full_size / 16);
|
||||
|
||||
tree inner_type = gccbrig_tree_type_for_hsa_type (inner_brig_type);
|
||||
|
||||
unsigned inner_size = gccbrig_hsa_type_bit_size (inner_brig_type);
|
||||
unsigned nunits = full_size / inner_size;
|
||||
tree_type = build_vector_type (inner_type, nunits);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (brig_type)
|
||||
{
|
||||
case BRIG_TYPE_NONE:
|
||||
tree_type = void_type_node;
|
||||
break;
|
||||
case BRIG_TYPE_B1:
|
||||
tree_type = boolean_type_node;
|
||||
break;
|
||||
case BRIG_TYPE_S8:
|
||||
case BRIG_TYPE_S16:
|
||||
case BRIG_TYPE_S32:
|
||||
case BRIG_TYPE_S64:
|
||||
/* Ensure a fixed width integer. */
|
||||
tree_type
|
||||
= build_nonstandard_integer_type
|
||||
(gccbrig_hsa_type_bit_size (brig_type), false);
|
||||
break;
|
||||
case BRIG_TYPE_U8:
|
||||
return unsigned_char_type_node;
|
||||
case BRIG_TYPE_U16:
|
||||
case BRIG_TYPE_U32:
|
||||
case BRIG_TYPE_U64:
|
||||
case BRIG_TYPE_B8: /* Handle bit vectors as unsigned ints. */
|
||||
case BRIG_TYPE_B16:
|
||||
case BRIG_TYPE_B32:
|
||||
case BRIG_TYPE_B64:
|
||||
case BRIG_TYPE_B128:
|
||||
case BRIG_TYPE_SIG32: /* Handle signals as integers for now. */
|
||||
case BRIG_TYPE_SIG64:
|
||||
tree_type = build_nonstandard_integer_type
|
||||
(gccbrig_hsa_type_bit_size (brig_type), true);
|
||||
break;
|
||||
case BRIG_TYPE_F16:
|
||||
tree_type = uint16_type_node;
|
||||
break;
|
||||
case BRIG_TYPE_F32:
|
||||
/* TODO: make sure that the alignment of the float are at least as
|
||||
strict than mandated by HSA, and conform to IEEE (like mandated
|
||||
by HSA). */
|
||||
tree_type = float_type_node;
|
||||
break;
|
||||
case BRIG_TYPE_F64:
|
||||
tree_type = double_type_node;
|
||||
break;
|
||||
case BRIG_TYPE_SAMP:
|
||||
case BRIG_TYPE_ROIMG:
|
||||
case BRIG_TYPE_WOIMG:
|
||||
case BRIG_TYPE_RWIMG:
|
||||
{
|
||||
/* Handle images and samplers as target-specific blobs of data
|
||||
that should be allocated earlier on from the runtime side.
|
||||
Create a void* that should be initialized to point to the blobs
|
||||
by the kernel launcher. Images and samplers are accessed
|
||||
via builtins that take void* as the reference. TODO: who and
|
||||
how these arrays should be initialized? */
|
||||
tree void_ptr = build_pointer_type (void_type_node);
|
||||
return void_ptr;
|
||||
}
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Drop const qualifiers. */
|
||||
return tree_type;
|
||||
}
|
53
gcc/brig/brigfrontend/brig-util.h
Normal file
53
gcc/brig/brigfrontend/brig-util.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* brig-util.h -- gccbrig utility functions
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef GCC_BRIG_UTIL_H
|
||||
#define GCC_BRIG_UTIL_H
|
||||
|
||||
#include "brig-to-generic.h"
|
||||
|
||||
bool gccbrig_hsa_opcode_op_output_p (BrigOpcode16_t opcode, int opnum);
|
||||
|
||||
unsigned gccbrig_hsa_type_bit_size (BrigType16_t t);
|
||||
|
||||
uint64_t gccbrig_to_uint64_t (const BrigUInt64 &brig_type);
|
||||
|
||||
int gccbrig_reg_size (const BrigOperandRegister *brig_reg);
|
||||
|
||||
std::string gccbrig_reg_name (const BrigOperandRegister *reg);
|
||||
|
||||
std::string gccbrig_type_name (BrigType16_t type);
|
||||
|
||||
std::string gccbrig_segment_name (BrigSegment8_t segment);
|
||||
|
||||
bool gccbrig_is_float_type (BrigType16_t type);
|
||||
|
||||
bool gccbrig_is_bit_operation (BrigOpcode16_t opcode);
|
||||
|
||||
BrigType16_t gccbrig_tree_type_to_hsa_type (tree tree_type);
|
||||
tree gccbrig_tree_type_for_hsa_type (BrigType16_t brig_type);
|
||||
|
||||
bool gccbrig_might_be_host_defined_var_p (const BrigDirectiveVariable *brigVar);
|
||||
|
||||
/* From hsa.h. */
|
||||
bool hsa_type_packed_p (BrigType16_t type);
|
||||
|
||||
#endif
|
264
gcc/brig/brigfrontend/brig-variable-handler.cc
Normal file
264
gcc/brig/brigfrontend/brig-variable-handler.cc
Normal file
|
@ -0,0 +1,264 @@
|
|||
/* brig-variable-handler.cc -- brig variable directive handling
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "brig-code-entry-handler.h"
|
||||
|
||||
#include "stringpool.h"
|
||||
#include "errors.h"
|
||||
#include "brig-machine.h"
|
||||
#include "brig-util.h"
|
||||
#include "print-tree.h"
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
tree
|
||||
brig_directive_variable_handler::build_variable
|
||||
(const BrigDirectiveVariable *brigVar, tree_code var_decltype)
|
||||
{
|
||||
std::string var_name = m_parent.get_mangled_name (brigVar);
|
||||
|
||||
bool is_definition = brigVar->modifier & BRIG_VARIABLE_DEFINITION;
|
||||
|
||||
tree name_identifier = get_identifier (var_name.c_str ());
|
||||
|
||||
tree var_decl;
|
||||
tree t;
|
||||
if (brigVar->type & BRIG_TYPE_ARRAY)
|
||||
{
|
||||
tree element_type
|
||||
= gccbrig_tree_type_for_hsa_type (brigVar->type & ~BRIG_TYPE_ARRAY);
|
||||
uint64_t element_count = gccbrig_to_uint64_t (brigVar->dim);
|
||||
if (is_definition && element_count == 0)
|
||||
fatal_error (UNKNOWN_LOCATION, "Array definition with zero elements.");
|
||||
if (var_decltype == PARM_DECL)
|
||||
t = build_pointer_type (element_type);
|
||||
else
|
||||
t = build_array_type_nelts (element_type, element_count);
|
||||
}
|
||||
else
|
||||
{
|
||||
t = gccbrig_tree_type_for_hsa_type (brigVar->type);
|
||||
}
|
||||
|
||||
size_t alignment = get_brig_var_alignment (brigVar);
|
||||
|
||||
if (brigVar->segment == BRIG_SEGMENT_READONLY
|
||||
|| brigVar->segment == BRIG_SEGMENT_KERNARG
|
||||
|| (brigVar->modifier & BRIG_VARIABLE_CONST))
|
||||
TYPE_READONLY (t) = 1;
|
||||
|
||||
TYPE_ADDR_SPACE (t) = gccbrig_get_target_addr_space_id (brigVar->segment);
|
||||
|
||||
var_decl = build_decl (UNKNOWN_LOCATION, var_decltype, name_identifier, t);
|
||||
|
||||
SET_DECL_ALIGN (var_decl, alignment * BITS_PER_UNIT);
|
||||
|
||||
/* Force the HSA alignments. */
|
||||
DECL_USER_ALIGN (var_decl) = 1;
|
||||
|
||||
TREE_USED (var_decl) = 1;
|
||||
|
||||
TREE_PUBLIC (var_decl) = 1;
|
||||
if (is_definition)
|
||||
DECL_EXTERNAL (var_decl) = 0;
|
||||
else
|
||||
DECL_EXTERNAL (var_decl) = 1; /* The definition is elsewhere. */
|
||||
|
||||
if (brigVar->init != 0)
|
||||
{
|
||||
gcc_assert (brigVar->segment == BRIG_SEGMENT_READONLY
|
||||
|| brigVar->segment == BRIG_SEGMENT_GLOBAL);
|
||||
|
||||
const BrigBase *cst_operand_data
|
||||
= m_parent.get_brig_operand_entry (brigVar->init);
|
||||
|
||||
tree initializer = NULL_TREE;
|
||||
if (cst_operand_data->kind == BRIG_KIND_OPERAND_CONSTANT_BYTES)
|
||||
initializer = get_tree_cst_for_hsa_operand
|
||||
((const BrigOperandConstantBytes *) cst_operand_data, t);
|
||||
else
|
||||
error ("variable initializers of type %x not implemented",
|
||||
cst_operand_data->kind);
|
||||
gcc_assert (initializer != NULL_TREE);
|
||||
DECL_INITIAL (var_decl) = initializer;
|
||||
}
|
||||
|
||||
if (var_decltype == PARM_DECL)
|
||||
{
|
||||
DECL_ARG_TYPE (var_decl) = TREE_TYPE (var_decl);
|
||||
DECL_EXTERNAL (var_decl) = 0;
|
||||
TREE_PUBLIC (var_decl) = 0;
|
||||
}
|
||||
|
||||
TREE_ADDRESSABLE (var_decl) = 1;
|
||||
|
||||
TREE_USED (var_decl) = 1;
|
||||
DECL_NONLOCAL (var_decl) = 1;
|
||||
DECL_ARTIFICIAL (var_decl) = 0;
|
||||
|
||||
return var_decl;
|
||||
}
|
||||
|
||||
size_t
|
||||
brig_directive_variable_handler::operator () (const BrigBase *base)
|
||||
{
|
||||
const BrigDirectiveVariable *brigVar = (const BrigDirectiveVariable *) base;
|
||||
|
||||
bool is_definition = brigVar->modifier & BRIG_VARIABLE_DEFINITION;
|
||||
|
||||
size_t var_size;
|
||||
tree var_type;
|
||||
if (brigVar->type & BRIG_TYPE_ARRAY)
|
||||
{
|
||||
tree element_type
|
||||
= gccbrig_tree_type_for_hsa_type (brigVar->type & ~BRIG_TYPE_ARRAY);
|
||||
uint64_t element_count = gccbrig_to_uint64_t (brigVar->dim);
|
||||
if (is_definition && element_count == 0)
|
||||
fatal_error (UNKNOWN_LOCATION, "Array definition with zero elements.");
|
||||
var_type = build_array_type_nelts (element_type, element_count);
|
||||
size_t element_size = tree_to_uhwi (TYPE_SIZE (element_type));
|
||||
var_size = element_size * element_count / 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
var_type = gccbrig_tree_type_for_hsa_type (brigVar->type);
|
||||
var_size = tree_to_uhwi (TYPE_SIZE (var_type)) / 8;
|
||||
}
|
||||
|
||||
size_t alignment = get_brig_var_alignment (brigVar);
|
||||
|
||||
if (m_parent.m_cf != NULL)
|
||||
m_parent.m_cf->m_function_scope_vars.insert (base);
|
||||
|
||||
std::string var_name = m_parent.get_mangled_name (brigVar);
|
||||
if (brigVar->segment == BRIG_SEGMENT_KERNARG)
|
||||
{
|
||||
/* Do not create a real variable, but only a table of
|
||||
offsets to the kernarg segment buffer passed as the
|
||||
single argument by the kernel launcher for later
|
||||
reference. Ignore kernel declarations. */
|
||||
if (m_parent.m_cf != NULL && m_parent.m_cf->m_func_decl != NULL_TREE)
|
||||
m_parent.m_cf->append_kernel_arg (brigVar, var_size, alignment);
|
||||
return base->byteCount;
|
||||
}
|
||||
else if (brigVar->segment == BRIG_SEGMENT_GROUP)
|
||||
{
|
||||
/* Handle group region variables similarly as kernargs:
|
||||
assign offsets to the group region on the fly when
|
||||
a new module scope or function scope group variable is
|
||||
introduced. These offsets will be then added to the
|
||||
group_base hidden pointer passed to the kernel in order to
|
||||
get the flat address. */
|
||||
if (!m_parent.has_group_variable (var_name))
|
||||
m_parent.append_group_variable (var_name, var_size, alignment);
|
||||
return base->byteCount;
|
||||
}
|
||||
else if (brigVar->segment == BRIG_SEGMENT_PRIVATE
|
||||
|| brigVar->segment == BRIG_SEGMENT_SPILL)
|
||||
{
|
||||
/* Private variables are handled like group variables,
|
||||
except that their offsets are multiplied by the work-item
|
||||
flat id, when accessed. */
|
||||
if (!m_parent.has_private_variable (var_name))
|
||||
m_parent.append_private_variable (var_name, var_size, alignment);
|
||||
return base->byteCount;
|
||||
}
|
||||
else if (brigVar->segment == BRIG_SEGMENT_GLOBAL
|
||||
|| brigVar->segment == BRIG_SEGMENT_READONLY)
|
||||
{
|
||||
tree def = is_definition ? NULL_TREE :
|
||||
m_parent.global_variable (var_name);
|
||||
|
||||
if (!is_definition && def != NULL_TREE)
|
||||
{
|
||||
/* We have a definition already for this declaration.
|
||||
Use the definition instead of the declaration. */
|
||||
}
|
||||
else if (gccbrig_might_be_host_defined_var_p (brigVar))
|
||||
{
|
||||
tree var_decl = build_variable (brigVar);
|
||||
m_parent.add_host_def_var_ptr (var_name, var_decl);
|
||||
}
|
||||
else
|
||||
{
|
||||
tree var_decl = build_variable (brigVar);
|
||||
/* Make all global variables program scope for now
|
||||
so we can get their address from the Runtime API. */
|
||||
DECL_CONTEXT (var_decl) = NULL_TREE;
|
||||
TREE_STATIC (var_decl) = 1;
|
||||
m_parent.add_global_variable (var_name, var_decl);
|
||||
}
|
||||
}
|
||||
else if (brigVar->segment == BRIG_SEGMENT_ARG)
|
||||
{
|
||||
|
||||
if (m_parent.m_cf->m_generating_arg_block)
|
||||
{
|
||||
tree var_decl = build_variable (brigVar);
|
||||
tree bind_expr = m_parent.m_cf->m_current_bind_expr;
|
||||
|
||||
DECL_CONTEXT (var_decl) = m_parent.m_cf->m_func_decl;
|
||||
DECL_CHAIN (var_decl) = BIND_EXPR_VARS (bind_expr);
|
||||
BIND_EXPR_VARS (bind_expr) = var_decl;
|
||||
TREE_PUBLIC (var_decl) = 0;
|
||||
|
||||
m_parent.m_cf->add_arg_variable (brigVar, var_decl);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Must be an incoming function argument which has
|
||||
been parsed in brig-function-handler.cc. No
|
||||
need to generate anything here. */
|
||||
}
|
||||
}
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
return base->byteCount;
|
||||
}
|
||||
|
||||
/* Returns the alignment for the given BRIG variable. In case the variable
|
||||
explicitly defines alignment and its larger than the natural alignment,
|
||||
returns it instead of the natural one. */
|
||||
|
||||
size_t
|
||||
brig_directive_variable_handler::get_brig_var_alignment
|
||||
(const BrigDirectiveVariable *brigVar)
|
||||
{
|
||||
|
||||
size_t defined_alignment
|
||||
= brigVar->align == BRIG_ALIGNMENT_NONE ? 0 : 1 << (brigVar->align - 1);
|
||||
size_t natural_alignment;
|
||||
if (brigVar->type & BRIG_TYPE_ARRAY)
|
||||
{
|
||||
tree element_type
|
||||
= gccbrig_tree_type_for_hsa_type (brigVar->type & ~BRIG_TYPE_ARRAY);
|
||||
size_t element_size = tree_to_uhwi (TYPE_SIZE (element_type));
|
||||
natural_alignment = element_size / BITS_PER_UNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
tree t = gccbrig_tree_type_for_hsa_type (brigVar->type);
|
||||
natural_alignment = tree_to_uhwi (TYPE_SIZE (t)) / BITS_PER_UNIT;
|
||||
}
|
||||
|
||||
return natural_alignment > defined_alignment
|
||||
? natural_alignment : defined_alignment;
|
||||
}
|
69
gcc/brig/brigfrontend/phsa.h
Normal file
69
gcc/brig/brigfrontend/phsa.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/* phsa.h -- interfacing between the gcc BRIG FE and the phsa runtime
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef PHSA_H
|
||||
#define PHSA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* This struct is used to pass information from the BRIG FE to the
|
||||
runtime of the finalizer kernel, its control directives etc.
|
||||
The data is passed raw in a special ELF section named
|
||||
phsa.kerneldesc.kernel_function_name. */
|
||||
|
||||
typedef struct __attribute__((__packed__))
|
||||
{
|
||||
/* Set to 1 in case the function is a kernel. */
|
||||
uint8_t is_kernel;
|
||||
/* The size of the group segment used by the kernel. */
|
||||
uint32_t group_segment_size;
|
||||
/* Size of the private segment used by a single work-item. */
|
||||
uint32_t private_segment_size;
|
||||
/* Total size of the kernel arguments. */
|
||||
uint32_t kernarg_segment_size;
|
||||
/* Maximum alignment of a kernel argument variable. */
|
||||
uint16_t kernarg_max_align;
|
||||
/* Maximum size (in bytes) of dynamic group memory. */
|
||||
uint32_t max_dynamic_group_size;
|
||||
/* Max number of work-items used to launch the kernel. */
|
||||
uint64_t max_flat_grid_size;
|
||||
/* Max number of work-items in a work-group used to launch the kernel. */
|
||||
uint32_t max_flat_workgroup_size;
|
||||
/* The grid size required by the kernel. */
|
||||
uint64_t required_grid_size[3];
|
||||
/* The work group size required by the kernel. */
|
||||
uint32_t required_workgroup_size[3];
|
||||
/* The number of dimensions required by the kernel. */
|
||||
uint8_t required_dim;
|
||||
|
||||
} phsa_descriptor;
|
||||
|
||||
/* The prefix to use in the ELF section containing descriptor for
|
||||
a function. */
|
||||
#define PHSA_DESC_SECTION_PREFIX "phsa.desc."
|
||||
#define PHSA_HOST_DEF_PTR_PREFIX "__phsa.host_def."
|
||||
|
||||
/* The frontend error messages are parsed by the host runtime, known
|
||||
prefix strings are used to separate the different runtime error
|
||||
codes. */
|
||||
#define PHSA_ERROR_PREFIX_INCOMPATIBLE_MODULE "Incompatible module:"
|
||||
|
||||
#endif
|
135
gcc/brig/brigspec.c
Normal file
135
gcc/brig/brigspec.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
/* brigspec.c -- Specific flags and argument handling of the gcc BRIG front end.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "gcc.h"
|
||||
#include "opts.h"
|
||||
|
||||
/* This bit is set if we saw a `-xfoo' language specification. */
|
||||
#define LANGSPEC (1 << 1)
|
||||
/* This bit is set if they did `-lm' or `-lmath'. */
|
||||
#define MATHLIB (1 << 2)
|
||||
/* This bit is set if they did `-lpthread'. */
|
||||
#define THREADLIB (1 << 3)
|
||||
/* This bit is set if they did `-lc'. */
|
||||
#define WITHLIBC (1 << 4)
|
||||
/* Skip this option. */
|
||||
#define SKIPOPT (1 << 5)
|
||||
|
||||
#ifndef MATH_LIBRARY
|
||||
#define MATH_LIBRARY "m"
|
||||
#endif
|
||||
#ifndef MATH_LIBRARY_PROFILE
|
||||
#define MATH_LIBRARY_PROFILE MATH_LIBRARY
|
||||
#endif
|
||||
|
||||
#define LIBHSAIL "hsail-rt"
|
||||
|
||||
void
|
||||
lang_specific_driver (struct cl_decoded_option **in_decoded_options,
|
||||
unsigned int *in_decoded_options_count,
|
||||
int *in_added_libraries)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
/* The new argument list will be contained in this. */
|
||||
struct cl_decoded_option *new_decoded_options;
|
||||
|
||||
/* An array used to flag each argument that needs a bit set for
|
||||
LANGSPEC, MATHLIB, or WITHLIBC. */
|
||||
int *args;
|
||||
|
||||
/* By default, we throw on the math library if we have one. */
|
||||
int need_math = (MATH_LIBRARY[0] != '\0');
|
||||
|
||||
/* True if we should add -shared-libgcc to the command-line. */
|
||||
int shared_libgcc = 1;
|
||||
|
||||
/* The total number of arguments with the new stuff. */
|
||||
unsigned int argc;
|
||||
|
||||
/* The argument list. */
|
||||
struct cl_decoded_option *decoded_options;
|
||||
|
||||
/* The number of libraries added in. */
|
||||
int added_libraries;
|
||||
|
||||
/* The total number of arguments with the new stuff. */
|
||||
int num_args = 1;
|
||||
|
||||
argc = *in_decoded_options_count;
|
||||
decoded_options = *in_decoded_options;
|
||||
added_libraries = *in_added_libraries;
|
||||
|
||||
args = XCNEWVEC (int, argc);
|
||||
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
switch (decoded_options[i].opt_index)
|
||||
{
|
||||
case OPT_o:
|
||||
break;
|
||||
|
||||
case OPT_SPECIAL_input_file:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure to have room for the trailing NULL argument. */
|
||||
num_args = argc + need_math + shared_libgcc + 10;
|
||||
new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
|
||||
|
||||
i = 0;
|
||||
j = 0;
|
||||
|
||||
/* Copy the 0th argument, i.e., the name of the program itself. */
|
||||
new_decoded_options[j++] = decoded_options[i++];
|
||||
|
||||
/* NOTE: We start at 1 now, not 0. */
|
||||
while (i < argc)
|
||||
{
|
||||
new_decoded_options[j] = decoded_options[i];
|
||||
|
||||
if ((args[i] & SKIPOPT) != 0)
|
||||
--j;
|
||||
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
|
||||
generate_option (OPT_l, LIBHSAIL, 1, CL_DRIVER, &new_decoded_options[j]);
|
||||
j++;
|
||||
|
||||
*in_decoded_options_count = j;
|
||||
*in_decoded_options = new_decoded_options;
|
||||
*in_added_libraries = added_libraries;
|
||||
}
|
||||
|
||||
/* Called before linking. Returns 0 on success and -1 on failure. */
|
||||
|
||||
int lang_specific_pre_link (void) /* Not used for Brig. */ { return 0; }
|
||||
|
||||
/* Number of extra output files that lang_specific_pre_link may generate. */
|
||||
|
||||
int lang_specific_extra_outfiles = 0; /* Not used for Brig. */
|
41
gcc/brig/config-lang.in
Normal file
41
gcc/brig/config-lang.in
Normal file
|
@ -0,0 +1,41 @@
|
|||
# config-lang.in -- Top level configure fragment for gcc BRIG (HSAIL) frontend.
|
||||
|
||||
# Copyright (C) 2015 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.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Configure looks for the existence of this file to auto-config each language.
|
||||
# We define several parameters used by configure:
|
||||
#
|
||||
# language - name of language as it would appear in $(LANGUAGES)
|
||||
# compilers - value to add to $(COMPILERS)
|
||||
|
||||
language="brig"
|
||||
|
||||
compilers="brig1\$(exeext)"
|
||||
|
||||
target_libs="target-libbrig target-libhsail-rt"
|
||||
|
||||
# The BRIG frontend is written in C++, so we need to build the C++
|
||||
# compiler during stage 1. Note: when cross-compiling / not bootstrapping,
|
||||
# this can be safely removed. gcc 4.9.1 force enables c++/libstdc++ to the
|
||||
# target compiler due to this.
|
||||
lang_requires_boot_languages=c++
|
||||
|
||||
gtfiles="\$(srcdir)/brig/brig-lang.c \$(srcdir)/brig/brig-c.h"
|
||||
|
||||
build_by_default="no"
|
28
gcc/brig/lang-specs.h
Normal file
28
gcc/brig/lang-specs.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
/* lang-specs.h -- gcc driver specs for BRIG (HSAIL) frontend.
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
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.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* This is the contribution to the `default_compilers' array in gcc.c
|
||||
for the BRIG (HSAIL) input. */
|
||||
|
||||
{".brig", "@brig", 0, 1, 0},
|
||||
{"@brig",
|
||||
"brig1 %i %(cc1_options) %{I*} %{L*} %D %{!fsyntax-only:%(invoke_as)}", 0, 1,
|
||||
0},
|
41
gcc/brig/lang.opt
Normal file
41
gcc/brig/lang.opt
Normal file
|
@ -0,0 +1,41 @@
|
|||
; lang.opt -- Options for the gcc BRIG (HSAIL) front end.
|
||||
|
||||
; Copyright (C) 2015 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.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License
|
||||
; along with GCC; see the file COPYING3. If not see
|
||||
; <http://www.gnu.org/licenses/>.
|
||||
|
||||
; See the GCC internals manual for a description of this file's format.
|
||||
|
||||
; Please try to keep this file in ASCII collating order.
|
||||
|
||||
Language
|
||||
BRIG
|
||||
|
||||
-dump
|
||||
BRIG Separate Alias(d)
|
||||
|
||||
-dump=
|
||||
BRIG Joined Alias(d)
|
||||
|
||||
L
|
||||
BRIG Joined Separate
|
||||
; Not documented
|
||||
|
||||
-output=
|
||||
BRIG Driver Joined Alias(o) MissingArgError(missing filename after %qs)
|
||||
|
||||
; This comment is to ensure we retain the blank line above.
|
|
@ -67,7 +67,10 @@ DEF_PRIMITIVE_TYPE (BT_LONGLONG, long_long_integer_type_node)
|
|||
DEF_PRIMITIVE_TYPE (BT_ULONGLONG, long_long_unsigned_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_INTMAX, intmax_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_UINTMAX, uintmax_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_UINT16, uint16_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_INT8, signed_char_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_INT16, short_integer_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_UINT8, char_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_UINT16, short_unsigned_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_UINT32, uint32_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_UINT64, uint64_type_node)
|
||||
DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (word_mode, 1))
|
||||
|
@ -167,6 +170,7 @@ DEF_FUNCTION_TYPE_0 (BT_FN_CONST_STRING, BT_CONST_STRING)
|
|||
DEF_FUNCTION_TYPE_0 (BT_FN_PID, BT_PID)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_INT, BT_INT)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_ULONG, BT_ULONG)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_FLOAT, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_0 (BT_FN_DOUBLE, BT_DOUBLE)
|
||||
/* For "long double" we use LONGDOUBLE (not LONG_DOUBLE) to
|
||||
|
@ -271,16 +275,29 @@ DEF_FUNCTION_TYPE_1 (BT_FN_VOID_VPTR, BT_VOID, BT_VOLATILE_PTR)
|
|||
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTRPTR, BT_VOID, BT_PTR_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_VOID_CONST_PTR, BT_VOID, BT_CONST_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT_UINT, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT_INT, BT_UINT, BT_INT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT_ULONG, BT_UINT, BT_ULONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT_LONG, BT_UINT, BT_LONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT_PTR, BT_UINT, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_ULONG_PTR, BT_ULONG, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_ULONG_ULONG, BT_ULONG, BT_ULONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_ULONGLONG_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT8_FLOAT, BT_INT8, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_INT16_FLOAT, BT_INT16, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_FLOAT, BT_UINT32, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_FLOAT, BT_UINT16, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT8_FLOAT, BT_UINT8, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_UINT16, BT_UINT16, BT_UINT16)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT32, BT_UINT32, BT_UINT32)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_UINT64, BT_UINT64, BT_UINT64)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_FLOAT, BT_UINT64, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_BOOL_INT, BT_BOOL, BT_INT)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_PTR_CONST_PTR, BT_PTR, BT_CONST_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_CONST_PTR_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_BND_CONST_PTR, BT_BND, BT_CONST_PTR)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_CONST_PTR_BND, BT_CONST_PTR, BT_BND)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_UINT32, BT_UINT16, BT_UINT32)
|
||||
DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT16, BT_UINT32, BT_UINT16)
|
||||
|
||||
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR, BT_FN_VOID_PTR)
|
||||
|
||||
|
@ -301,18 +318,52 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_CONST_STRING_FILEPTR,
|
|||
BT_INT, BT_CONST_STRING, BT_FILEPTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_INT_FILEPTR,
|
||||
BT_INT, BT_INT, BT_FILEPTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_UINT16_UINT16_UINT16,
|
||||
BT_UINT16, BT_UINT16, BT_UINT16)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_PTR_INT,
|
||||
BT_INT, BT_PTR, BT_INT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_UINT_PTR_UINT,
|
||||
BT_UINT, BT_PTR, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_LONG_PTR_LONG,
|
||||
BT_LONG, BT_PTR, BT_LONG)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_ULONG_PTR_ULONG,
|
||||
BT_ULONG, BT_PTR, BT_ULONG)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTRMODE_PTR,
|
||||
BT_VOID, BT_PTRMODE, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_PTRMODE,
|
||||
BT_VOID, BT_PTR, BT_PTRMODE)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT64_UINT64,
|
||||
BT_VOID, BT_UINT64, BT_UINT64)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VALIST_REF_VALIST_ARG,
|
||||
BT_VOID, BT_VALIST_REF, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_LONG_LONG_LONG,
|
||||
BT_LONG, BT_LONG, BT_LONG)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_UINT8_UINT8_UINT8,
|
||||
BT_UINT8, BT_UINT8, BT_UINT8)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT8_INT8_INT8,
|
||||
BT_INT8, BT_INT8, BT_INT8)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT16_INT16_INT16,
|
||||
BT_INT16, BT_INT16, BT_INT16)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_INT_INT,
|
||||
BT_INT, BT_INT, BT_INT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_UINT_FLOAT_UINT,
|
||||
BT_UINT, BT_FLOAT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_UINT_UINT,
|
||||
BT_FLOAT, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_ULONG_UINT_UINT,
|
||||
BT_ULONG, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_ULONG_UINT_PTR,
|
||||
BT_ULONG, BT_UINT, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_ULONG_ULONG_ULONG,
|
||||
BT_ULONG, BT_ULONG, BT_ULONG)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_UINT_UINT_UINT,
|
||||
BT_UINT, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_INT_PTR_CONST_STRING,
|
||||
BT_INT, BT_PTR, BT_CONST_STRING)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_SIZE,
|
||||
BT_VOID, BT_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_PTR,
|
||||
BT_VOID, BT_UINT, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_FLOAT_FLOAT_FLOAT,
|
||||
BT_FLOAT, BT_FLOAT, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_DOUBLE_DOUBLE_DOUBLE,
|
||||
|
@ -408,6 +459,7 @@ DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_SIZE_CONST_VPTR, BT_BOOL, BT_SIZE,
|
|||
BT_CONST_VOLATILE_PTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_BOOL_INT_BOOL, BT_BOOL, BT_INT, BT_BOOL)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT_UINT, BT_VOID, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_UINT_UINT_PTR, BT_UINT, BT_UINT, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_SIZE, BT_PTR, BT_CONST_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_PTR_CONST_PTR_CONST_PTR, BT_PTR, BT_CONST_PTR, BT_CONST_PTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTRPTR_CONST_PTR, BT_VOID, BT_PTR_PTR, BT_CONST_PTR)
|
||||
|
@ -415,6 +467,8 @@ DEF_FUNCTION_TYPE_2 (BT_FN_VOID_CONST_PTR_SIZE, BT_VOID, BT_CONST_PTR, BT_SIZE)
|
|||
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_BND, BT_VOID, BT_PTR, BT_BND)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_CONST_PTR_CONST_PTR_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR, BT_CONST_PTR)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_BND_CONST_PTR_SIZE, BT_BND, BT_CONST_PTR, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_2 (BT_FN_UINT32_UINT64_PTR,
|
||||
BT_UINT32, BT_UINT64, BT_PTR)
|
||||
|
||||
DEF_POINTER_TYPE (BT_PTR_FN_VOID_PTR_PTR, BT_FN_VOID_PTR_PTR)
|
||||
|
||||
|
@ -444,6 +498,20 @@ DEF_FUNCTION_TYPE_3 (BT_FN_INT_FILEPTR_CONST_STRING_VALIST_ARG,
|
|||
BT_INT, BT_FILEPTR, BT_CONST_STRING, BT_VALIST_ARG)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_PTR_PTR_PTR,
|
||||
BT_INT, BT_PTR, BT_PTR, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_INT_INT_UINT_UINT,
|
||||
BT_INT, BT_INT, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_UINT_UINT_UINT_UINT,
|
||||
BT_UINT, BT_UINT, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_UINT_UINT_UINT_PTR,
|
||||
BT_UINT, BT_UINT, BT_UINT, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_UINT_ULONG_ULONG_UINT,
|
||||
BT_UINT, BT_ULONG, BT_ULONG, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_ULONG_ULONG_ULONG_ULONG,
|
||||
BT_ULONG, BT_ULONG, BT_ULONG, BT_ULONG)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_LONG_LONG_UINT_UINT,
|
||||
BT_LONG, BT_LONG, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_ULONG_ULONG_UINT_UINT,
|
||||
BT_ULONG, BT_ULONG, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_STRING_CONST_STRING_CONST_STRING_INT,
|
||||
BT_STRING, BT_CONST_STRING, BT_CONST_STRING, BT_INT)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_FLOAT_FLOAT_FLOAT_FLOAT,
|
||||
|
@ -512,6 +580,10 @@ DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_ULONG_ULONG_ULONGPTR, BT_BOOL, BT_ULONG,
|
|||
BT_ULONG, BT_PTR_ULONG)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_BOOL_ULONGLONG_ULONGLONG_ULONGLONGPTR, BT_BOOL,
|
||||
BT_ULONGLONG, BT_ULONGLONG, BT_PTR_ULONGLONG)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_UINT32_UINT64_PTR,
|
||||
BT_VOID, BT_UINT32, BT_UINT64, BT_PTR)
|
||||
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_UINT32_UINT32_PTR,
|
||||
BT_VOID, BT_UINT32, BT_UINT32, BT_PTR)
|
||||
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR,
|
||||
BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR)
|
||||
|
@ -523,6 +595,12 @@ DEF_FUNCTION_TYPE_4 (BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE,
|
|||
BT_PTR, BT_PTR, BT_CONST_PTR, BT_SIZE, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_PTR_PTR_INT_SIZE_SIZE,
|
||||
BT_PTR, BT_PTR, BT_INT, BT_SIZE, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_UINT_UINT_UINT_UINT_UINT,
|
||||
BT_UINT, BT_UINT, BT_UINT, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_UINT_FLOAT_FLOAT_FLOAT_FLOAT,
|
||||
BT_UINT, BT_FLOAT, BT_FLOAT, BT_FLOAT, BT_FLOAT)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_ULONG_ULONG_ULONG_UINT_UINT,
|
||||
BT_ULONG, BT_ULONG, BT_ULONG, BT_UINT, BT_UINT)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE,
|
||||
BT_STRING, BT_STRING, BT_CONST_STRING, BT_SIZE, BT_SIZE)
|
||||
DEF_FUNCTION_TYPE_4 (BT_FN_INT_FILEPTR_INT_CONST_STRING_VALIST_ARG,
|
||||
|
|
|
@ -1000,5 +1000,48 @@ DEF_GCC_BUILTIN (BUILT_IN_LINE, "LINE", BT_FN_INT, ATTR_NOTHROW_LEAF_LIST)
|
|||
/* Pointer Bounds Checker builtins. */
|
||||
#include "chkp-builtins.def"
|
||||
|
||||
/* Do not expose the BRIG builtins by default gcc-wide, but only privately in
|
||||
the BRIG FE as long as there are no references for them in the middle end
|
||||
or any of the upstream backends. */
|
||||
|
||||
#ifndef DEF_HSAIL_BUILTIN
|
||||
#define DEF_HSAIL_BUILTIN(ENUM, HSAIL_OPCODE, HSAIL_TYPE, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN_STUB (ENUM, "__builtin_" NAME)
|
||||
#endif
|
||||
|
||||
/* HSAIL atomic builtins do not have separate identifying opcodes. */
|
||||
|
||||
#ifndef DEF_HSAIL_ATOMIC_BUILTIN
|
||||
#define DEF_HSAIL_ATOMIC_BUILTIN(ENUM, ATOMIC_OPCODE, HSAIL_TYPE, NAME, \
|
||||
TYPE, ATTRS) \
|
||||
DEF_BUILTIN_STUB (ENUM, "__builtin_" NAME)
|
||||
#endif
|
||||
|
||||
/* HSAIL saturating arithmetics builtins. */
|
||||
|
||||
#ifndef DEF_HSAIL_SAT_BUILTIN
|
||||
#define DEF_HSAIL_SAT_BUILTIN(ENUM, BRIG_OPCODE, HSAIL_TYPE, NAME, \
|
||||
TYPE, ATTRS) \
|
||||
DEF_BUILTIN_STUB (ENUM, "__builtin_" NAME)
|
||||
#endif
|
||||
|
||||
/* HSAIL builtins used internally by the frontend. */
|
||||
|
||||
#ifndef DEF_HSAIL_INTR_BUILTIN
|
||||
#define DEF_HSAIL_INTR_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN_STUB (ENUM, "__builtin_" NAME)
|
||||
#endif
|
||||
|
||||
/* HSAIL saturated conversions. */
|
||||
|
||||
#ifndef DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN
|
||||
#define DEF_HSAIL_CVT_ZEROI_SAT_BUILTIN(ENUM, HSAIL_DEST_TYPE, HSAIL_SRC_TYPE, \
|
||||
NAME, TYPE, ATTRS) \
|
||||
DEF_BUILTIN_STUB (ENUM, "__builtin_" NAME)
|
||||
#endif
|
||||
|
||||
/* HSAIL/BRIG frontend builtins. */
|
||||
#include "brig-builtins.def"
|
||||
|
||||
#undef DEF_BUILTIN_CHKP
|
||||
#undef DEF_BUILTIN
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
GCC stands for ``GNU Compiler Collection''. GCC is an integrated
|
||||
distribution of compilers for several major programming languages. These
|
||||
languages currently include C, C++, Objective-C, Objective-C++,
|
||||
Fortran, Ada, and Go.
|
||||
Fortran, Ada, Go, and BRIG (HSAIL).
|
||||
|
||||
The abbreviation @dfn{GCC} has multiple meanings in common use. The
|
||||
current official meaning is ``GNU Compiler Collection'', which refers
|
||||
|
|
|
@ -2665,7 +2665,10 @@ separately.
|
|||
|
||||
Second, you must have the testing tools installed. This includes
|
||||
@uref{http://www.gnu.org/software/dejagnu/,,DejaGnu}, Tcl, and Expect;
|
||||
the DejaGnu site has links to these.
|
||||
the DejaGnu site has links to these. For running the BRIG frontend
|
||||
tests, a tool to assemble the binary BRIGs from HSAIL text,
|
||||
@uref{https://github.com/HSAFoundation/HSAIL-Tools/,,HSAILasm} must
|
||||
be installed.
|
||||
|
||||
If the directories where @command{runtest} and @command{expect} were
|
||||
installed are not in the @env{PATH}, you may need to set the following
|
||||
|
|
|
@ -1338,6 +1338,9 @@ traditional preprocessor).
|
|||
@item @var{file}.go
|
||||
Go source code.
|
||||
|
||||
@item @var{file}.brig
|
||||
BRIG files (binary representation of HSAIL).
|
||||
|
||||
@item @var{file}.ads
|
||||
Ada source code file that contains a library unit declaration (a
|
||||
declaration of a package, subprogram, or generic, or a generic
|
||||
|
@ -1386,6 +1389,7 @@ assembler assembler-with-cpp
|
|||
ada
|
||||
f77 f77-cpp-input f95 f95-cpp-input
|
||||
go
|
||||
brig
|
||||
@end smallexample
|
||||
|
||||
@item -x none
|
||||
|
|
|
@ -301,6 +301,14 @@ available online, see @uref{http://gcc.gnu.org/readings.html}
|
|||
As of the GCC 4.7.1 release, GCC supports the Go 1 language standard,
|
||||
described at @uref{http://golang.org/doc/go1.html}.
|
||||
|
||||
@section HSA Intermediate Language (HSAIL)
|
||||
|
||||
GCC can compile the binary representation (BRIG) of the HSAIL text format as
|
||||
described in HSA Programmer's Reference Manual version 1.0.1. This
|
||||
capability is typically utilized to implement the HSA runtime API's HSAIL
|
||||
finalization extension for a gcc supported processor. HSA standards are
|
||||
freely available at @uref{http://www.hsafoundation.com/standards/}.
|
||||
|
||||
@section References for Other Languages
|
||||
|
||||
@xref{Top, GNAT Reference Manual, About This Guide, gnat_rm,
|
||||
|
|
|
@ -1,3 +1,23 @@
|
|||
2017-01-24 Pekka Jääskeläinen <pekka@parmance.com>
|
||||
Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* lib/brig-dg.exp: New file.
|
||||
* lib/brig.exp: Likewise.
|
||||
* brig.dg/README: Likewise.
|
||||
* brig.dg/dg.exp: Likewise.
|
||||
* brig.dg/test/gimple/alloca.hsail: Likewise.
|
||||
* brig.dg/test/gimple/atomics.hsail: Likewise.
|
||||
* brig.dg/test/gimple/branches.hsail: Likewise.
|
||||
* brig.dg/test/gimple/fbarrier.hsail: Likewise.
|
||||
* brig.dg/test/gimple/function_calls.hsail: Likewise.
|
||||
* brig.dg/test/gimple/kernarg.hsail: Likewise.
|
||||
* brig.dg/test/gimple/mem.hsail: Likewise.
|
||||
* brig.dg/test/gimple/mulhi.hsail: Likewise.
|
||||
* brig.dg/test/gimple/packed.hsail: Likewise.
|
||||
* brig.dg/test/gimple/smoke_test.hsail: Likewise.
|
||||
* brig.dg/test/gimple/variables.hsail: Likewise.
|
||||
* brig.dg/test/gimple/vector.hsail: Likewise.
|
||||
|
||||
2017-01-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* g++.dg/asan/asan_test.C: Enable on all *-*-linux* targets that
|
||||
|
|
12
gcc/testsuite/brig.dg/README
Normal file
12
gcc/testsuite/brig.dg/README
Normal file
|
@ -0,0 +1,12 @@
|
|||
BRIG (HSAIL) frontend test cases
|
||||
--------------------------------
|
||||
|
||||
The suite consists of "smoke tests" that test several features of
|
||||
the compilation and regression tests, but is not an exhaustive test
|
||||
suite for all HSAIL instructions. The HSA PRM conformance suite
|
||||
is supposed to be used for that.
|
||||
|
||||
HSAILasm is required for converting the text HSAIL files to BRIGs
|
||||
which the compiler consumes. It can be built from
|
||||
https://github.com/HSAFoundation/HSAIL-Tools
|
||||
|
31
gcc/testsuite/brig.dg/dg.exp
Normal file
31
gcc/testsuite/brig.dg/dg.exp
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Copyright (C) 2009-2014 Free Software Foundation, Inc.
|
||||
|
||||
# This program 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 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# GCC testsuite that uses the `dg.exp' driver.
|
||||
|
||||
load_lib brig-dg.exp
|
||||
|
||||
# Initialize `dg'.
|
||||
dg-init
|
||||
|
||||
if [expr [llength [auto_execok HSAILasm]] > 0] {
|
||||
dg-runtest [find $srcdir/$subdir *.hsail] "" ""
|
||||
} else {
|
||||
unsupported "All BRIG FE tests require HSAILasm in PATH."
|
||||
}
|
||||
|
||||
# All done.
|
||||
dg-finish
|
37
gcc/testsuite/brig.dg/test/gimple/alloca.hsail
Normal file
37
gcc/testsuite/brig.dg/test/gimple/alloca.hsail
Normal file
|
@ -0,0 +1,37 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* Tests for alloca. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
|
||||
prog function &subfunction(arg_u32 %return_value)() {
|
||||
alloca_align(1)_u32 $s2, 256;
|
||||
st_arg_u32 $s2, [%return_value];
|
||||
ret;
|
||||
};
|
||||
|
||||
prog kernel &kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_global_u32 $s0, [$d0];
|
||||
|
||||
alloca_align(256)_u32 $s1, 16;
|
||||
{
|
||||
arg_u32 %return_value;
|
||||
call &subfunction(%return_value)();
|
||||
ld_arg_u32 $s1, [%return_value];
|
||||
}
|
||||
ld_kernarg_u64 $d1, [%output_ptr];
|
||||
st_global_u32 $s1, [$d0];
|
||||
};
|
||||
|
||||
/* { dg-final { scan-tree-dump "s2 = __builtin___hsail_alloca \\\(256, 1, __context\\\);" "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump "s1 = __builtin___hsail_alloca \\\(16, 256, __context\\\);" "gimple" } } */
|
||||
|
||||
|
||||
/* Both functions should have an alloca frame push and pop. */
|
||||
/* { dg-final { scan-tree-dump-times "__builtin___hsail_alloca_push_frame \\\(__context\\\);" 2 "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__builtin___hsail_alloca_pop_frame \\\(__context\\\);" 2 "gimple" } } */
|
33
gcc/testsuite/brig.dg/test/gimple/atomics.hsail
Normal file
33
gcc/testsuite/brig.dg/test/gimple/atomics.hsail
Normal file
|
@ -0,0 +1,33 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* Test for atomic instructions. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-original" } */
|
||||
|
||||
prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
|
||||
atomic_ld_global_rlx_system_b32 $s0, [$d0];
|
||||
atomic_add_global_rlx_system_u32 $s1, [$d0 + 4], $s0;
|
||||
|
||||
ld_kernarg_u64 $d0, [%output_ptr];
|
||||
atomicnoret_st_global_rlx_system_b32 [$d0], $s2;
|
||||
|
||||
atomicnoret_min_global_rlx_system_u32 [$d0 + 4], $s1;
|
||||
|
||||
ret;
|
||||
};
|
||||
|
||||
/* The atomic loads are implemented by casting to an atomic pointer. */
|
||||
/* { dg-final { scan-tree-dump "s0 = VIEW_CONVERT_EXPR<unsigned int>\\\(\\\*\\\(atomic unsigned int \\\*\\\)" "original"} } */
|
||||
|
||||
/* The atomic add should call a gcc builtin. */
|
||||
/* { dg-final { scan-tree-dump "= __sync_fetch_and_add_4 \\\(" "original"} } */
|
||||
|
||||
/* The atomic stores are implemented by casting to an atomic pointer. */
|
||||
/* { dg-final { scan-tree-dump "\\\*\\\(atomic unsigned int \\\*\\\) d0 = s2;" "original"} } */
|
||||
|
||||
/* The atomic min is implemented by a custom builtin. */
|
||||
/* { dg-final { scan-tree-dump "builtin_out.\[0-9\]+ = __builtin___hsail_atomic_min_u32 \\\(" "original"} } */
|
58
gcc/testsuite/brig.dg/test/gimple/branches.hsail
Normal file
58
gcc/testsuite/brig.dg/test/gimple/branches.hsail
Normal file
|
@ -0,0 +1,58 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* Test different style of branches. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
|
||||
prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_global_u64 $d1, [$d0];
|
||||
ld_global_u64 $d2, [$d0 + 8];
|
||||
|
||||
ld_global_u32 $s0, [$d0 + 16];
|
||||
ld_global_u32 $s1, [$d0 + 20];
|
||||
|
||||
sbr_width(all)_u32 $s1 [@case0, @case1, @case2];
|
||||
@case0:
|
||||
st_global_u64 0, [$d0];
|
||||
br @out;
|
||||
@case1:
|
||||
st_global_u64 1, [$d0];
|
||||
br @out;
|
||||
@case2:
|
||||
st_global_u64 2, [$d0];
|
||||
@out:
|
||||
cmp_eq_u32_u32 $s2, $s1, $s0;
|
||||
cvt_b1_u32 $c0, $s2;
|
||||
|
||||
cbr_width(all)_b1 $c0, @true_branch;
|
||||
@false_branch:
|
||||
st_global_u64 $d1, [$d0];
|
||||
|
||||
@true_branch:
|
||||
ld_kernarg_u64 $d0, [%output_ptr];
|
||||
|
||||
st_global_u32 $s2, [$d0 + 8];
|
||||
br @skip;
|
||||
st_global_u32 $s3, [$d0 + 12];
|
||||
|
||||
@skip:
|
||||
ret;
|
||||
};
|
||||
|
||||
/* sbr is converted to a switch */
|
||||
/* { dg-final { scan-tree-dump "switch \\\(s1\\\) <default: <D.\[0-9\]+>, case 0: <D.\[0-9\]+>, case 1: <D.\[0-9\]+>, case 2: <D.\[0-9\]+>>" "gimple"} } */
|
||||
|
||||
/* br @out converted to gotos */
|
||||
/* { dg-final { scan-tree-dump-times "goto @out" 2 "gimple"} } */
|
||||
|
||||
/* the comparison instruction */
|
||||
/* { dg-final { scan-tree-dump "c0 = s2 != 0;" "gimple" } } */
|
||||
|
||||
/* cbr to an if clause */
|
||||
/* { dg-final { scan-tree-dump "if \\\(c0 != 0\\\) goto @true_branch; else goto <D.\[0-9\]+>;" "gimple" } } */
|
||||
|
||||
/* br @skip converted to a goto */
|
||||
/* { dg-final { scan-tree-dump "goto @skip" "gimple"} } */
|
74
gcc/testsuite/brig.dg/test/gimple/fbarrier.hsail
Normal file
74
gcc/testsuite/brig.dg/test/gimple/fbarrier.hsail
Normal file
|
@ -0,0 +1,74 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* Tests for fbarrier. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
|
||||
fbarrier &fb_module_scope;
|
||||
|
||||
prog function &subfunction(arg_u32 %return_value)() {
|
||||
|
||||
workitemflatabsid_u32 $s3;
|
||||
cvt_b1_u32 $c1, $s3;
|
||||
cbr_width(all)_b1 $c1, @skip_fbar;
|
||||
waitfbar &fb_module_scope;
|
||||
@skip_fbar:
|
||||
|
||||
st_arg_u32 $s3, [%return_value];
|
||||
ret;
|
||||
};
|
||||
|
||||
prog kernel &kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
fbarrier %fb_func_scope;
|
||||
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_global_u32 $s0, [$d0];
|
||||
|
||||
workitemflatabsid_u32 $s1;
|
||||
cvt_b1_u32 $c1, $s1;
|
||||
cbr_width(all)_b1 $c1, @skip_init;
|
||||
|
||||
initfbar &fb_module_scope;
|
||||
initfbar %fb_func_scope;
|
||||
|
||||
joinfbar &fb_module_scope;
|
||||
|
||||
@skip_init:
|
||||
barrier_width(all);
|
||||
|
||||
joinfbar %fb_func_scope;
|
||||
|
||||
{
|
||||
arg_u32 %return_value;
|
||||
call &subfunction(%return_value)();
|
||||
ld_arg_u32 $s1, [%return_value];
|
||||
}
|
||||
arrivefbar %fb_func_scope;
|
||||
|
||||
ld_kernarg_u64 $d1, [%output_ptr];
|
||||
st_global_u32 $s1, [$d0];
|
||||
|
||||
workitemflatabsid_u32 $s1;
|
||||
cvt_b1_u32 $c0, $s1;
|
||||
cbr_width(all)_b1 $c0, @skip_fini;
|
||||
|
||||
releasefbar &fb_module_scope;
|
||||
releasefbar %fb_func_scope;
|
||||
|
||||
@skip_fini:
|
||||
|
||||
};
|
||||
/* fbarriers are allocated from the group memory in the order of
|
||||
appearance. The current implementation allocates 32B per fbarrier. */
|
||||
|
||||
/* { dg-final { scan-tree-dump "__hsail_waitfbar \\\(0, __context\\\);" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "__hsail_initfbar \\\(0, __context\\\);" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "__hsail_initfbar \\\(32, __context\\\);" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "__hsail_joinfbar \\\(0, __context\\\);" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "@skip_init:\[\n ]+__builtin___hsail_barrier \\\(__context\\\);\[\n ]+__builtin___hsail_joinfbar \\\(32, __context\\\);" "gimple"} } */
|
||||
|
||||
/* { dg-final { scan-tree-dump "__hsail_arrivefbar \\\(32, __context\\\);" "gimple"} } */
|
||||
|
||||
/* { dg-final { scan-tree-dump "__hsail_releasefbar \\\(0, __context\\\);\[\n ]+__builtin___hsail_releasefbar \\\(32, __context\\\);" "gimple"} } */
|
59
gcc/testsuite/brig.dg/test/gimple/function_calls.hsail
Normal file
59
gcc/testsuite/brig.dg/test/gimple/function_calls.hsail
Normal file
|
@ -0,0 +1,59 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* Function calls and argument passing. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
|
||||
prog function &subfunction(arg_u32 %return_value)(arg_f32 %float_arg, arg_f64 %double_arg, arg_f16 %half_arg) {
|
||||
ld_arg_f32 $s0, [%float_arg];
|
||||
cvt_u32_f32 $s0, $s0;
|
||||
|
||||
ld_arg_f64 $d0, [%double_arg];
|
||||
cvt_u32_f64 $s1, $d0;
|
||||
|
||||
ld_arg_f16 $s2, [%half_arg];
|
||||
cvt_u32_f16 $s2, $s2;
|
||||
|
||||
add_u32 $s3, $s0, $s1;
|
||||
add_u32 $s3, $s3, $s2;
|
||||
|
||||
st_arg_u32 $s3, [%return_value];
|
||||
ret;
|
||||
};
|
||||
|
||||
prog kernel &kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_global_u32 $s0, [$d0];
|
||||
{
|
||||
arg_f32 %float_arg;
|
||||
arg_f64 %double_arg;
|
||||
arg_f16 %half_arg;
|
||||
arg_u32 %return_value;
|
||||
|
||||
st_arg_f32 12.0f, [%float_arg];
|
||||
st_arg_f64 640.0d, [%double_arg];
|
||||
st_arg_f16 12.0h, [%half_arg];
|
||||
|
||||
call &subfunction(%return_value)(%float_arg, %double_arg, %half_arg);
|
||||
|
||||
ld_arg_u32 $s1, [%return_value];
|
||||
}
|
||||
ld_kernarg_u64 $d1, [%output_ptr];
|
||||
st_global_u32 $s1, [$d0];
|
||||
};
|
||||
|
||||
/* The generated function call should have the incoming arguments and three hidden arguments. */
|
||||
|
||||
/* { dg-final { scan-tree-dump "_\[0-9\]+ = subfunction \\\(_kernel.float_arg.\[_0-9\]+, _kernel.double_arg.\[_0-9\]+, _kernel.half_arg.\[_0-9\]+, __context, __group_base_addr, __private_base_addr\\\);" "gimple"} } */
|
||||
|
||||
/* The callee should refer directly to the scalar arguments when it reads them. */
|
||||
/* { dg-final { scan-tree-dump "= float_arg;" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "= double_arg;" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "= half_arg;" "gimple"} } */
|
||||
|
||||
/* The return value is stored to a temporary before returned. */
|
||||
/* { dg-final { scan-tree-dump "_retvalue_temp = s3;" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "D.\[0-9\]+ = _retvalue_temp;" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "return D.\[0-9\]+;" "gimple"} } */
|
25
gcc/testsuite/brig.dg/test/gimple/kernarg.hsail
Normal file
25
gcc/testsuite/brig.dg/test/gimple/kernarg.hsail
Normal file
|
@ -0,0 +1,25 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* Tests for kernarg addressing modes. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-original" } */
|
||||
|
||||
prog kernel &Kernel(kernarg_u64 %input[4], kernarg_u64 %output_ptr, kernarg_u64 %i)
|
||||
{
|
||||
ld_kernarg_u64 $d0, [%i];
|
||||
ld_kernarg_u64 $d0, [%input][$d0 + 1];
|
||||
|
||||
ld_kernarg_u64 $d1, [%output_ptr];
|
||||
st_global_u64 $d0, [$d1];
|
||||
|
||||
ret;
|
||||
};
|
||||
|
||||
/* [%i] */
|
||||
/* { dg-final { scan-tree-dump " = \\\*\\\(unsigned long \\\*\\\) \\\(__args \\\+ 40\\\);" "original"} } */
|
||||
|
||||
/* [%input][$d0 + 1] */
|
||||
/* { dg-final { scan-tree-dump "\\\*\\\(unsigned long \\\*\\\) \\\(\\\(VIEW_CONVERT_EXPR<void \\\*>\\\(\\\(unsigned long\\\) __args\\\) \\\+ \\\(unsigned long\\\) d0\\\) \\\+ 1\\\);" "original"} } */
|
||||
|
||||
|
39
gcc/testsuite/brig.dg/test/gimple/mem.hsail
Normal file
39
gcc/testsuite/brig.dg/test/gimple/mem.hsail
Normal file
|
@ -0,0 +1,39 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* Tests for load/store addressing modes. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-original" } */
|
||||
|
||||
prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %input_ptr2, kernarg_u64 %output_ptr)
|
||||
{
|
||||
global_u32 %global_array[4];
|
||||
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_kernarg_u64 $d2, [%input_ptr2];
|
||||
ld_global_u32 $s0, [$d0];
|
||||
ld_global_u64 $d1, [$d2 + 4];
|
||||
|
||||
ld_global_u32 $s2, [%global_array][$d1 + 4];
|
||||
|
||||
ld_kernarg_u64 $d0, [%output_ptr];
|
||||
st_global_u32 $s0, [$d0];
|
||||
st_global_u32 $s1, [$d0 + 4];
|
||||
st_global_u32 $s2, [$d0 + 8];
|
||||
|
||||
ret;
|
||||
};
|
||||
|
||||
/* %input_ptr, %input_ptr2 and %output_ptr accesses should generate offsets to the __args array */
|
||||
/* { dg-final { scan-tree-dump "__args;\[\n \]+d0 =" "original"} } */
|
||||
/* { dg-final { scan-tree-dump "\\\(__args \\\+ 8\\\);\[\n \]+d2 =" "original"} } */
|
||||
/* { dg-final { scan-tree-dump "\\\(__args \\\+ 16\\\);\[\n \]+d0 =" "original"} } */
|
||||
|
||||
/* ld_global_u32 $s0, [$d0] */
|
||||
/* { dg-final { scan-tree-dump "\\\*\\\(unsigned int \\\*\\\) d0;\[\n \]+s0 =" "original"} } */
|
||||
|
||||
/* ld_global_u64 $d1, [$d2 + 4] pointer arithmetics*/
|
||||
/* { dg-final { scan-tree-dump "d2 \\\+ 4\\\);\[\n \]+d1 = " "original"} } */
|
||||
|
||||
/* ld_global_u32 $s2, [%global_array][$d1 + 4]; is the most complex form */
|
||||
/* { dg-final { scan-tree-dump "\\\(unsigned long\\\) &_Kernel.global_array\\\) \\\+ \\\(unsigned long\\\) d1\\\) \\\+ 4" "original" } } */
|
33
gcc/testsuite/brig.dg/test/gimple/mulhi.hsail
Normal file
33
gcc/testsuite/brig.dg/test/gimple/mulhi.hsail
Normal file
|
@ -0,0 +1,33 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* Test high part multiplies. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
|
||||
prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_global_u64 $d1, [$d0];
|
||||
ld_global_u64 $d2, [$d0 + 8];
|
||||
|
||||
ld_global_u32 $s0, [$d0 + 16];
|
||||
ld_global_u32 $s1, [$d0 + 20];
|
||||
|
||||
mulhi_s32 $s2, $s0, $s1;
|
||||
mulhi_s64 $d2, $d1, $d2;
|
||||
|
||||
mad24hi_s32 $s3, $s0, $s1, $s2;
|
||||
mul24hi_s32 $s3, $s3, $s1;
|
||||
|
||||
ld_kernarg_u64 $d0, [%output_ptr];
|
||||
st_global_u64 $d1, [$d0];
|
||||
st_global_u32 $s2, [$d0 + 8];
|
||||
st_global_u32 $s3, [$d0 + 12];
|
||||
|
||||
ret;
|
||||
};
|
||||
|
||||
/* All of the hipart mults areImplemented using MULT_HIGHPART_EXPR (h*). */
|
||||
/* { dg-final { scan-tree-dump-times " h\\\* " 4 "gimple"} } */
|
||||
|
78
gcc/testsuite/brig.dg/test/gimple/packed.hsail
Normal file
78
gcc/testsuite/brig.dg/test/gimple/packed.hsail
Normal file
|
@ -0,0 +1,78 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* Test for different cases of packed instruction controls. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-gimple -fdump-tree-original" } */
|
||||
|
||||
prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_global_b128 $q0, [$d0];
|
||||
|
||||
add_pp_u8x16 $q1, $q0, u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
|
||||
|
||||
/* Broadcast the 15 as it's the lowest element (pos 0) in the resulting vector. */
|
||||
add_ps_u8x16 $q2, $q1, u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
|
||||
|
||||
/* Broadcast the lowest element of q1. */
|
||||
add_sp_u8x16 $q3, $q1, $q2;
|
||||
|
||||
/* Perform a scalar computation with the lowest element of both inputs and store it to the lowest element of dest. */
|
||||
add_ss_u8x16 $q4, $q2, $q3;
|
||||
|
||||
/* Saturating arithmetics variations. */
|
||||
add_pp_sat_u8x16 $q5, $q4, u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
|
||||
|
||||
/* Broadcast the 15 as it's the lowest element (pos 0) in the resulting vector. */
|
||||
add_ps_sat_u8x16 $q6, $q5, u8x16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
|
||||
|
||||
/* Broadcast the lowest element of q1. */
|
||||
add_sp_sat_u8x16 $q7, $q6, $q5;
|
||||
|
||||
/* Perform a scalar computation with the lowest element of both inputs and store it to the lowest element of dest. */
|
||||
add_ss_sat_u8x16 $q8, $q7, $q6;
|
||||
|
||||
/* Single operand vector computation. */
|
||||
neg_p_s16x8 $q9, $q8;
|
||||
|
||||
ld_kernarg_u64 $d0, [%output_ptr];
|
||||
st_global_b128 $q8, [$d0];
|
||||
|
||||
ret;
|
||||
};
|
||||
|
||||
/* The b128 load is done using uint128_t*.
|
||||
/* { dg-final { scan-tree-dump "q0 = VIEW_CONVERT_EXPR<uint128_t>\\\(mem_read.\[0-9\]+\\\);" "original"} } */
|
||||
|
||||
/* Before arithmetics, the uint128_t is casted to a vector datatype. */
|
||||
/* { dg-final { scan-tree-dump "<vector\\\(16\\\) unsigned char>\\\(q0\\\) \\\+ \\\{" "original"} } */
|
||||
|
||||
/* The u8x16 constant is generated to an array with elements in reverse order */
|
||||
/* in comparison to the HSAIL syntax. */
|
||||
/* { dg-final { scan-tree-dump "\\\+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }" "original"} } */
|
||||
|
||||
/* After arithmetics, the vector DT is casted back to a uint128_t. */
|
||||
/* { dg-final { scan-tree-dump "q1 = VIEW_CONVERT_EXPR<uint128_t>" "original"} } */
|
||||
|
||||
/* Broadcasted the constant vector's lowest element and summed it up in the next line. */
|
||||
/* { dg-final { scan-tree-dump "= { 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 };\[\n \]+_\[0-9\]+ = _\[0-9\]+ \\\+ _\[0-9\]+;" "gimple"} } */
|
||||
|
||||
/* Broadcasted the registers lowest element via a VEC_PERM_EXPR that has an all-zeros mask. */
|
||||
/* { dg-final { scan-tree-dump "VEC_PERM_EXPR <_\[0-9\]+, _\[0-9\]+, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }>;" "gimple" } } */
|
||||
|
||||
/* For the add_ss we assume performing the computation over the whole vector is cheaper than */
|
||||
/* extracting the scalar and performing a scalar operation. This aims to stay in the vector
|
||||
/* datapath as long as possible. */
|
||||
/* { dg-final { scan-tree-dump "_\[0-9\]+ = VIEW_CONVERT_EXPR<vector\\\(16\\\) unsigned char>\\\(q2\\\);\[\n \]+_\[0-9\]+ = VIEW_CONVERT_EXPR<vector\\\(16\\\) unsigned char>\\\(q3\\\);\[\n \]+_\[0-9\]+ = _\[0-9\]+ \\\+ _\[0-9\]+;" "gimple" } } */
|
||||
|
||||
/* Insert the lowest element of the result to the lowest element of the result register. */
|
||||
/* { dg-final { scan-tree-dump "= VEC_PERM_EXPR <_\[0-9\]+, new_output.\[0-9\]+_\[0-9\]+, { 16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }>;" "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump "q4 = VIEW_CONVERT_EXPR<uint128_t>\\\(s_output.\[0-9\]+_\[0-9\]+\\\);" "gimple" } } */
|
||||
|
||||
/* The saturating arithmetics are (curently) implemented using scalar builtin calls. */
|
||||
/* { dg-final { scan-tree-dump-times "= __builtin___hsail_sat_add_u8" 64 "gimple" } } */
|
||||
|
||||
/* A single operand vector instr (neg.) */
|
||||
/* { dg-final { scan-tree-dump " = VIEW_CONVERT_EXPR<vector\\\(8\\\) signed short>\\\(q8\\\);\[\n \]+_\[0-9\]+ = -_\[0-9\]+;\[\n \]+" "gimple" } } */
|
91
gcc/testsuite/brig.dg/test/gimple/smoke_test.hsail
Normal file
91
gcc/testsuite/brig.dg/test/gimple/smoke_test.hsail
Normal file
|
@ -0,0 +1,91 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* A basic smoke test. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
|
||||
prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_global_u32 $s0, [$d0];
|
||||
ld_global_u32 $s1, [$d0 + 4];
|
||||
|
||||
add_u32 $s2, $s0, $s1;
|
||||
add_u32 $s3, $s0, 4294967295;
|
||||
|
||||
ld_kernarg_u64 $d0, [%output_ptr];
|
||||
st_global_u32 $s2, [$d0];
|
||||
st_global_u32 $s3, [$d0 + 4];
|
||||
|
||||
ret;
|
||||
};
|
||||
|
||||
prog kernel &KernelWithBarrier(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_global_u32 $s0, [$d0];
|
||||
ld_global_u32 $s1, [$d0 + 4];
|
||||
|
||||
add_u32 $s2, $s0, $s1;
|
||||
|
||||
barrier_width(all);
|
||||
|
||||
add_u32 $s3, $s0, 4294967295;
|
||||
|
||||
ld_kernarg_u64 $d0, [%output_ptr];
|
||||
st_global_u32 $s2, [$d0];
|
||||
st_global_u32 $s3, [$d0 + 4];
|
||||
|
||||
ret;
|
||||
};
|
||||
|
||||
/* The kernel function itself should have a fingerprint as follows */
|
||||
/* _Kernel (unsigned char * __args, void * __context, void * __group_base_addr, void * __private_base_addr) */
|
||||
/* { dg-final { scan-tree-dump "_Kernel \\\(unsigned char \\\* __args, void \\\* __context, void \\\* __group_base_addr, void \\\* __private_base_addr\\\)" "gimple"} } */
|
||||
|
||||
/* ld_kernarg: mem_read.0 = MEM[(unsigned long *)__args]; */
|
||||
/* { dg-final { scan-tree-dump "mem_read.\[0-9\] = MEM\\\[\\\(unsigned long \\\*\\\)__args\\\];" "gimple"} } */
|
||||
|
||||
/* The latter ld_global_u32 should be visible as a pointer dereference (after pointer arithmetics on a temporary var): */
|
||||
/* mem_read.2 = *D.1691; */
|
||||
/* { dg-final { scan-tree-dump "mem_read.\[0-9\] = \\\*\[_0-9\]+;" "gimple"} } */
|
||||
|
||||
/* add_u32s should generate +operators */
|
||||
/* { dg-final { scan-tree-dump "s2 = s0 \\\+ s1;" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "s3 = s0 \\\+ 4294967295;" "gimple"} } */
|
||||
|
||||
/* The latter st_global_u32 should be visible as a pointer dereference (after pointer arithmetics on a temporary var): */
|
||||
/* *D.1694 = s3; */
|
||||
/* { dg-final { scan-tree-dump "\\\*\[_0-9\]+ = s3;" "gimple"} } */
|
||||
|
||||
/* The return inside the kernel should be generated to a goto to the end of the kernel. */
|
||||
/* goto __kernel_exit; */
|
||||
/* __kernel_exit: */
|
||||
/* { dg-final { scan-tree-dump "goto __kernel_exit;" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "__kernel_exit:" "gimple"} } */
|
||||
|
||||
/* Expecting a work item loop because there are no barrier calls. */
|
||||
/* { dg-final { scan-tree-dump "if \\\(__local_x < __cur_wg_size_x\\\) goto __wi_loop_x; else goto" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "if \\\(__local_y < __cur_wg_size_y\\\) goto __wi_loop_y; else goto" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "if \\\(__local_z < __cur_wg_size_z\\\) goto __wi_loop_z; else goto" "gimple"} } */
|
||||
|
||||
/* The launcher should call __hsail_launch_wg_function in this case: */
|
||||
/* Kernel (void * __context, void * __group_base_addr) */
|
||||
/* { dg-final { scan-tree-dump "Kernel \\\(void \\\* __context, void \\\* __group_base_addr\\\)" "gimple"} } */
|
||||
/* { dg-final { scan-tree-dump "__hsail_launch_wg_function \\\(_Kernel, __context, __group_base_addr\\\);" "gimple"} }*/
|
||||
|
||||
/* The kernel should have the magic metadata section injected to the ELF. */
|
||||
/* TODO: this should be disabled in case not outputting to an ELF. */
|
||||
/* Currently ELF is assumed by the brig frontend. Do not check for the context */
|
||||
/* as it is likely to change. */
|
||||
/* { dg-final { scan-tree-dump "\\\.pushsection phsa\\\.desc\\\.Kernel" "gimple"} }*/
|
||||
|
||||
/* The kernel with the barrier call should have the barrier builtin call in between the two summations. */
|
||||
/* { dg-final { scan-tree-dump "s2 = s0 \\\+ s1;\[\n \]+__builtin___hsail_barrier \\\(__context\\\);\[\n \]+s3 = s0 \\\+ 4294967295;" "gimple"} } */
|
||||
|
||||
/* The kernel with the barrier call's launcher function should call the thread-spawning function. */
|
||||
/* { dg-final { scan-tree-dump "__hsail_launch_kernel \\\(_KernelWithBarrier, __context, __group_base_addr\\\);" "gimple" } } */
|
||||
|
||||
|
||||
|
124
gcc/testsuite/brig.dg/test/gimple/variables.hsail
Normal file
124
gcc/testsuite/brig.dg/test/gimple/variables.hsail
Normal file
|
@ -0,0 +1,124 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* Tests for different variable scopes and address spaces. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-gimple" } */
|
||||
|
||||
prog align(256) private_u32 &prog_private;
|
||||
private_u32 &mod_private;
|
||||
|
||||
prog group_u32 &prog_group;
|
||||
group_u32 &mod_group;
|
||||
|
||||
prog global_u32 &prog_global;
|
||||
global_u32 &mod_global;
|
||||
|
||||
decl prog global_u32 &prog_global_host_def;
|
||||
|
||||
prog readonly_u32 &prog_readonly;
|
||||
readonly_u32 &mod_readonly;
|
||||
|
||||
prog function &subfunction(arg_u32 %return_value)(arg_u32 %arg) {
|
||||
|
||||
private_u32 %func_private;
|
||||
group_u32 %func_group;
|
||||
align(256) global_u32 %func_global;
|
||||
readonly_u32 %func_readonly;
|
||||
|
||||
ld_private_u32 $s200, [%func_private];
|
||||
st_private_u32 $s200, [&prog_private];
|
||||
|
||||
ld_group_u32 $s203, [%func_group];
|
||||
st_group_u32 $s203, [&prog_group];
|
||||
|
||||
ld_global_u32 $s204, [%func_global];
|
||||
st_global_u32 $s204, [&prog_global];
|
||||
|
||||
ld_readonly_u32 $s205, [%func_readonly];
|
||||
st_global_u32 $s205, [%func_global];
|
||||
|
||||
st_arg_u32 $s2, [%return_value];
|
||||
ret;
|
||||
};
|
||||
|
||||
prog kernel &kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
private_u32 %kern_private;
|
||||
group_u32 %kern_group;
|
||||
global_u32 %kern_global;
|
||||
readonly_u32 %kern_readonly;
|
||||
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_global_u32 $s0, [$d0];
|
||||
|
||||
ld_private_u32 $s2, [&prog_private];
|
||||
st_private_u32 $s2, [%kern_private];
|
||||
ld_private_u32 $s3, [&mod_private];
|
||||
st_private_u32 $s3, [&prog_private];
|
||||
|
||||
ld_group_u32 $s4, [&prog_group];
|
||||
st_group_u32 $s4, [%kern_group];
|
||||
ld_group_u32 $s5, [&mod_group];
|
||||
st_group_u32 $s5, [&prog_group];
|
||||
|
||||
ld_global_u32 $s6, [&prog_global];
|
||||
st_global_u32 $s6, [%kern_global];
|
||||
ld_global_u32 $s7, [&mod_global];
|
||||
st_global_u32 $s7, [&prog_global];
|
||||
|
||||
ld_readonly_u32 $s8, [&prog_readonly];
|
||||
st_global_u32 $s8, [%kern_global];
|
||||
ld_readonly_u32 $s9, [&mod_readonly];
|
||||
st_global_u32 $s9, [&prog_global];
|
||||
|
||||
ld_readonly_u32 $s10, [%kern_readonly];
|
||||
st_global_u32 $s10, [%kern_global];
|
||||
ld_readonly_u32 $s11, [%kern_readonly];
|
||||
st_global_u32 $s11, [&prog_global_host_def];
|
||||
|
||||
{
|
||||
arg_u32 %arg;
|
||||
arg_u32 %return_value;
|
||||
st_arg_u32 $s1, [%arg];
|
||||
call &subfunction(%return_value)(%arg);
|
||||
ld_arg_u32 $s1, [%return_value];
|
||||
}
|
||||
ld_kernarg_u64 $d1, [%output_ptr];
|
||||
st_global_u32 $s1, [$d0];
|
||||
};
|
||||
|
||||
/* Private variable offsets assigned in the order of their appearance */
|
||||
/*
|
||||
prog_private @0 (align 256) -> until 254 to ensure all WIs
|
||||
mod_private @256 have their chunks aligned
|
||||
func_private @260
|
||||
kern_private @264
|
||||
*/
|
||||
|
||||
/* Group variable offsets assigned in the order of their appearance */
|
||||
/*
|
||||
prog_group @0 (2)
|
||||
mod_group @4 (4)
|
||||
func_group @8 (1)
|
||||
kern_group @12 (3)
|
||||
*/
|
||||
|
||||
/* { dg-final { scan-tree-dump "\\\+ 8;.*\\\+ 12;.*\\\+ 4;" "gimple" } } */
|
||||
|
||||
/* The "mangling" of the global and readonly vars. */
|
||||
/* { dg-final { scan-tree-dump "\[ \]*prog_global = s204;" "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump "\.module.mod_global;" "gimple" } } */
|
||||
|
||||
/* Host defined variables need indirect access as the address is
|
||||
known only at run time. */
|
||||
/* { dg-final { scan-tree-dump "\\\*\\\__phsa.host_def.prog_global_host_def.\[0-9\]+_\[0-9\]+ = s11;" "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump "\.subfunction.func_global;" "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump "\.subfunction.func_readonly;" "gimple" } } */
|
||||
|
||||
/* { dg-final { scan-tree-dump "kernel.kern_global" "gimple" } } */
|
||||
/* { dg-final { scan-tree-dump "kernel.kern_readonly" "gimple" } } */
|
||||
|
||||
|
57
gcc/testsuite/brig.dg/test/gimple/vector.hsail
Normal file
57
gcc/testsuite/brig.dg/test/gimple/vector.hsail
Normal file
|
@ -0,0 +1,57 @@
|
|||
module &module:1:0:$full:$large:$default;
|
||||
|
||||
/* A test for vector operands. */
|
||||
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fdump-tree-original" } */
|
||||
|
||||
prog kernel &Kernel(kernarg_u64 %input_ptr, kernarg_u64 %output_ptr)
|
||||
{
|
||||
ld_kernarg_u64 $d0, [%input_ptr];
|
||||
ld_v2_global_f32 ($s0, $s1), [$d0];
|
||||
ld_v3_global_f32 ($s2, $s3, $s4), [$d0 + 8];
|
||||
ld_v4_global_f32 ($s5, $s6, $s7, $s8), [$d0 + 20];
|
||||
|
||||
add_f32 $s9, $s0, $s1;
|
||||
combine_v2_b64_b32 $d2, ($s1, $s0);
|
||||
combine_v2_b64_b32 $d3, ($s2, $s3);
|
||||
|
||||
add_pp_f32x2 $d4, $d2, $d3;
|
||||
|
||||
expand_v2_b32_b64 ($s0, $s3), $d4;
|
||||
|
||||
ld_kernarg_u64 $d1, [%output_ptr];
|
||||
st_v2_global_f32 ($s0, $s1), [$d1];
|
||||
st_v3_global_f32 ($s2, $s3, $s4), [$d1 + 8];
|
||||
st_v4_global_f32 ($s5, $s6, $s7, $s8), [$d1 + 20];
|
||||
|
||||
ret;
|
||||
};
|
||||
|
||||
/* The v2 load is done via casting to a vector datatype ptr. */
|
||||
/* { dg-final { scan-tree-dump " = MEM\\\[\\\(vector\\\(2\\\) <float:32> \\\*\\\)" "original"} } */
|
||||
|
||||
/* The v3 load is scalarized (at the moment) due to gcc requiring 2's exponent wide vectors. */
|
||||
/* { dg-final { scan-tree-dump "s0 = VIEW_CONVERT_EXPR<unsigned int>\\\(BIT_FIELD_REF <mem_read.\[0-9\]+, 32, 0>\\\);\[\n ]+s1 = VIEW_CONVERT_EXPR<unsigned int>\\\(BIT_FIELD_REF <mem_read.\[0-9\]+, 32, 32>\\\);" "original"} } */
|
||||
|
||||
/* The v4 load is done via casting to a vector datatype ptr. */
|
||||
/* { dg-final { scan-tree-dump " = MEM\\\[\\\(vector\\\(4\\\) <float:32> \\\*\\\)" "original"} } */
|
||||
|
||||
/* The combines are generated to vector constructors. */
|
||||
/* { dg-final { scan-tree-dump "{s1, s0}" "original"} } */
|
||||
/* { dg-final { scan-tree-dump "{s2, s3}" "original"} } */
|
||||
|
||||
/* Expands to BIT_FIELD_REFs. */
|
||||
/* { dg-final { scan-tree-dump "s0 = BIT_FIELD_REF <d4, 32, 0>;" "original"} } */
|
||||
/* { dg-final { scan-tree-dump "s3 = BIT_FIELD_REF <d4, 32, 32>;" "original"} } */
|
||||
|
||||
/* The v1 store is done via casting to a vector datatype ptr and constructing a vector from the inputs. */
|
||||
/* { dg-final { scan-tree-dump "MEM\\\[\\\(vector\\\(2\\\) <float:32> \\\*\\\)\\\(<float:32> \\\*\\\) d1\\\] = " "original"} } */
|
||||
|
||||
/* The v3 store is scalarized (at the moment) due to gcc requiring 2's exponent wide vectors. */
|
||||
/* { dg-final { scan-tree-dump "\\\*\\\(<float:32> \\\*\\\) \\\(\\\(sizetype\\\) d1 \\\+ 8\\\) \\\+ 0 = VIEW_CONVERT_EXPR<<float:32>>\\\(s2\\\);" "original"} } */
|
||||
/* { dg-final { scan-tree-dump "\\\*\\\(<float:32> \\\*\\\) \\\(\\\(sizetype\\\) d1 \\\+ 8\\\) \\\+ 4 = VIEW_CONVERT_EXPR<<float:32>>\\\(s3\\\);" "original"} } */
|
||||
/* { dg-final { scan-tree-dump "\\\*\\\(<float:32> \\\*\\\) \\\(\\\(sizetype\\\) d1 \\\+ 8\\\) \\\+ 8 = VIEW_CONVERT_EXPR<<float:32>>\\\(s4\\\);" "original"} } */
|
||||
|
||||
/* The v4 store is done via casting to a vector datatype and constructing a vector from the inputs. */
|
||||
/* { dg-final { scan-tree-dump "MEM\\\[\\\(vector\\\(4\\\) <float:32> \\\*\\\)\\\(<float:32> \\\*\\\) \\\(\\\(sizetype\\\) d1 \\\+ 20\\\)\\\] = {VIEW_CONVERT_EXPR<<float:32>>\\\(s5\\\), VIEW_CONVERT_EXPR<<float:32>>\\\(s6\\\), VIEW_CONVERT_EXPR<<float:32>>\\\(s7\\\), VIEW_CONVERT_EXPR<<float:32>>\\\(s8\\\)};" "original"} } */
|
29
gcc/testsuite/lib/brig-dg.exp
Normal file
29
gcc/testsuite/lib/brig-dg.exp
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Copyright (C) 2009-2014 Free Software Foundation, Inc.
|
||||
|
||||
# This program 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 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib gcc-dg.exp
|
||||
|
||||
# Define brig callbacks for dg.exp.
|
||||
|
||||
proc brig-dg-test { prog do_what extra_tool_flags } {
|
||||
set result \
|
||||
[gcc-dg-test-1 brig_target_compile $prog $do_what $extra_tool_flags]
|
||||
|
||||
set comp_output [lindex $result 0]
|
||||
set output_file [lindex $result 1]
|
||||
|
||||
return [list $comp_output $output_file]
|
||||
}
|
40
gcc/testsuite/lib/brig.exp
Normal file
40
gcc/testsuite/lib/brig.exp
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Copyright (C) 2009-2016 Free Software Foundation, Inc.
|
||||
|
||||
# This program 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 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GCC; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
load_lib prune.exp
|
||||
load_lib gcc-defs.exp
|
||||
load_lib timeout.exp
|
||||
load_lib target-libpath.exp
|
||||
#
|
||||
# brig_target_compile -- compile a HSAIL input to BRIG using HSAILasm and then
|
||||
# compile the BRIG to target ISA using gcc
|
||||
|
||||
proc brig_target_compile { source dest type options } {
|
||||
global tmpdir
|
||||
global testname_with_flags
|
||||
if { [file extension $source] == ".hsail" } {
|
||||
# We cannot assume all inputs are .hsail as the dg machinery
|
||||
# calls this for a some c files to check linker plugin support or
|
||||
# similar.
|
||||
set brig_source ${tmpdir}/[file tail ${source}].brig
|
||||
exec HSAILasm $source -o ${brig_source}
|
||||
set source ${brig_source}
|
||||
# Change the testname the .brig.
|
||||
set testname_with_flags [file tail $source]
|
||||
}
|
||||
return [target_compile $source $dest $type $options]
|
||||
}
|
||||
|
|
@ -1,3 +1,8 @@
|
|||
2017-01-24 Pekka Jääskeläinen <pekka@parmance.com>
|
||||
Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* hsa.h: Moved here from libgomp/plugin/hsa.h.
|
||||
|
||||
2017-01-04 Richard Earnshaw <rearnsha@arm.com>
|
||||
Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2017-01-24 Pekka Jääskeläinen <pekka@parmance.com>
|
||||
Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* plugin/hsa.h: Moved to top level include.
|
||||
* plugin/plugin-hsa.c: Chanfgd include of hsa.h accordingly.
|
||||
|
||||
2017-01-21 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR other/79046
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#include <pthread.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <plugin/hsa.h>
|
||||
#include <hsa.h>
|
||||
#include <plugin/hsa_ext_finalize.h>
|
||||
#include <dlfcn.h>
|
||||
#include "libgomp-plugin.h"
|
||||
|
|
27
libhsail-rt/ChangeLog
Normal file
27
libhsail-rt/ChangeLog
Normal file
|
@ -0,0 +1,27 @@
|
|||
2017-01-24 Pekka Jääskeläinen <pekka@parmance.com>
|
||||
Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* Makefile.am: New file.
|
||||
* target-config.h.in: Likewise.
|
||||
* configure.ac: Likewise.
|
||||
* configure: Likewise.
|
||||
* config.h.in: Likewise.
|
||||
* aclocal.m4: Likewise.
|
||||
* README: Likewise.
|
||||
* Makefile.in: Likewise.
|
||||
* include/internal/fibers.h: Likewise.
|
||||
* include/internal/phsa-queue-interface.h: Likewise.
|
||||
* include/internal/phsa-rt.h: Likewise.
|
||||
* include/internal/workitems.h: Likewise.
|
||||
* rt/arithmetic.c: Likewise.
|
||||
* rt/atomics.c: Likewise.
|
||||
* rt/bitstring.c: Likewise.
|
||||
* rt/fbarrier.c: Likewise.
|
||||
* rt/fibers.c: Likewise.
|
||||
* rt/fp16.c: Likewise.
|
||||
* rt/misc.c: Likewise.
|
||||
* rt/multimedia.c: Likewise.
|
||||
* rt/queue.c: Likewise.
|
||||
* rt/sat_arithmetic.c: Likewise.
|
||||
* rt/segment.c: Likewise.
|
||||
* rt/workitems.c: Likewise.
|
124
libhsail-rt/Makefile.am
Normal file
124
libhsail-rt/Makefile.am
Normal file
|
@ -0,0 +1,124 @@
|
|||
# Makefile.am -- libhsail-rt library Makefile.
|
||||
|
||||
# Starting point copied from libcilkrts:
|
||||
# @copyright
|
||||
# Copyright (C) 2011, 2013, Intel Corporation
|
||||
# All rights reserved.
|
||||
#
|
||||
# @copyright
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# @copyright
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
|
||||
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# libhsail-rt modifications:
|
||||
# Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
# for General Processor Tech.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
# Process this file with autoreconf to produce Makefile.in.
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
|
||||
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
|
||||
|
||||
MAINT_CHARSET = latin1
|
||||
|
||||
mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
WARN_CFLAGS = $(WARN_FLAGS) $(WERROR)
|
||||
|
||||
# -I/-D flags to pass when compiling.
|
||||
AM_CPPFLAGS = -I$(srcdir)/rt -I$(srcdir)/include/internal
|
||||
|
||||
AM_CFLAGS = \
|
||||
-I $(srcdir)/../include \
|
||||
-I $(srcdir)/../libgcc \
|
||||
-I $(MULTIBUILDTOP)../../gcc/include $(PTH_CFLAGS)
|
||||
|
||||
toolexeclib_LTLIBRARIES = libhsail-rt.la
|
||||
|
||||
runtime_files = \
|
||||
rt/arithmetic.c \
|
||||
rt/atomics.c \
|
||||
rt/bitstring.c \
|
||||
rt/fbarrier.c \
|
||||
rt/fp16.c \
|
||||
rt/misc.c \
|
||||
rt/multimedia.c \
|
||||
rt/queue.c \
|
||||
rt/sat_arithmetic.c \
|
||||
rt/segment.c \
|
||||
rt/workitems.c \
|
||||
rt/fibers.c
|
||||
|
||||
libhsail_rt_la_SOURCES = $(runtime_files)
|
||||
libhsail_rt_la_LDFLAGS = -rpath '$(libdir)'
|
||||
|
||||
# Work around what appears to be a GNU make bug handling MAKEFLAGS
|
||||
# values defined in terms of make variables, as is the case for CC and
|
||||
# friends when we are called from the top level Makefile.
|
||||
AM_MAKEFLAGS = \
|
||||
"AR_FLAGS=$(AR_FLAGS)" \
|
||||
"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
|
||||
"CFLAGS=$(CFLAGS)" \
|
||||
"CXXFLAGS=$(CXXFLAGS)" \
|
||||
"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
|
||||
"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
|
||||
"INSTALL=$(INSTALL)" \
|
||||
"INSTALL_DATA=$(INSTALL_DATA)" \
|
||||
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
|
||||
"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
|
||||
"JC1FLAGS=$(JC1FLAGS)" \
|
||||
"LDFLAGS=$(LDFLAGS)" \
|
||||
"LIBCFLAGS=$(LIBCFLAGS)" \
|
||||
"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
|
||||
"MAKE=$(MAKE)" \
|
||||
"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
|
||||
"PICFLAG=$(PICFLAG)" \
|
||||
"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
|
||||
"SHELL=$(SHELL)" \
|
||||
"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
|
||||
"exec_prefix=$(exec_prefix)" \
|
||||
"infodir=$(infodir)" \
|
||||
"libdir=$(libdir)" \
|
||||
"prefix=$(prefix)" \
|
||||
"includedir=$(includedir)" \
|
||||
"AR=$(AR)" \
|
||||
"AS=$(AS)" \
|
||||
"LD=$(LD)" \
|
||||
"LIBCFLAGS=$(LIBCFLAGS)" \
|
||||
"NM=$(NM)" \
|
||||
"PICFLAG=$(PICFLAG)" \
|
||||
"RANLIB=$(RANLIB)" \
|
||||
"DESTDIR=$(DESTDIR)"
|
||||
|
||||
MAKEOVERRIDES=
|
||||
|
||||
|
740
libhsail-rt/Makefile.in
Normal file
740
libhsail-rt/Makefile.in
Normal file
|
@ -0,0 +1,740 @@
|
|||
# Makefile.in generated by automake 1.11.6 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
|
||||
# Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# Makefile.am -- libhsail-rt library Makefile.
|
||||
|
||||
# Starting point copied from libcilkrts:
|
||||
# @copyright
|
||||
# Copyright (C) 2011, 2013, Intel Corporation
|
||||
# All rights reserved.
|
||||
#
|
||||
# @copyright
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# @copyright
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
|
||||
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# libhsail-rt modifications:
|
||||
# Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
# for General Processor Tech.
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
# Process this file with autoreconf to produce Makefile.in.
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__make_dryrun = \
|
||||
{ \
|
||||
am__dry=no; \
|
||||
case $$MAKEFLAGS in \
|
||||
*\\[\ \ ]*) \
|
||||
echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
|
||||
| grep '^AM OK$$' >/dev/null || am__dry=yes;; \
|
||||
*) \
|
||||
for am__flg in $$MAKEFLAGS; do \
|
||||
case $$am__flg in \
|
||||
*=*|--*) ;; \
|
||||
*n*) am__dry=yes; break;; \
|
||||
esac; \
|
||||
done;; \
|
||||
esac; \
|
||||
test $$am__dry = yes; \
|
||||
}
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
target_triplet = @target@
|
||||
subdir = .
|
||||
DIST_COMMON = README $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
|
||||
$(top_srcdir)/configure $(am__configure_deps) \
|
||||
$(srcdir)/target-config.h.in $(srcdir)/../mkinstalldirs \
|
||||
$(srcdir)/../depcomp
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
|
||||
$(top_srcdir)/../config/lead-dot.m4 \
|
||||
$(top_srcdir)/../config/multi.m4 $(top_srcdir)/../libtool.m4 \
|
||||
$(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
|
||||
$(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||
configure.lineno config.status.lineno
|
||||
CONFIG_HEADER = target-config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__uninstall_files_from_dir = { \
|
||||
test -z "$$files" \
|
||||
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|
||||
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
|
||||
$(am__cd) "$$dir" && rm -f $$files; }; \
|
||||
}
|
||||
am__installdirs = "$(DESTDIR)$(toolexeclibdir)"
|
||||
LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
|
||||
libhsail_rt_la_LIBADD =
|
||||
am__dirstamp = $(am__leading_dot)dirstamp
|
||||
am__objects_1 = rt/arithmetic.lo rt/atomics.lo rt/bitstring.lo \
|
||||
rt/fbarrier.lo rt/fp16.lo rt/misc.lo rt/multimedia.lo \
|
||||
rt/queue.lo rt/sat_arithmetic.lo rt/segment.lo rt/workitems.lo \
|
||||
rt/fibers.lo
|
||||
am_libhsail_rt_la_OBJECTS = $(am__objects_1)
|
||||
libhsail_rt_la_OBJECTS = $(am_libhsail_rt_la_OBJECTS)
|
||||
libhsail_rt_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(libhsail_rt_la_LDFLAGS) $(LDFLAGS) -o $@
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||
depcomp = $(SHELL) $(top_srcdir)/../depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(libhsail_rt_la_SOURCES)
|
||||
am__can_run_installinfo = \
|
||||
case $$AM_UPDATE_INFO_DIR in \
|
||||
n|no|NO) false;; \
|
||||
*) (install-info --version) >/dev/null 2>&1;; \
|
||||
esac
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CXX = @CXX@
|
||||
CXXCPP = @CXXCPP@
|
||||
CXXDEPMODE = @CXXDEPMODE@
|
||||
CXXFLAGS = @CXXFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_CXX = @ac_ct_CXX@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
config_dir = @config_dir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target = @target@
|
||||
target_alias = @target_alias@
|
||||
target_cpu = @target_cpu@
|
||||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
toolexecdir = @toolexecdir@
|
||||
toolexeclibdir = @toolexeclibdir@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = foreign subdir-objects
|
||||
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
|
||||
MAINT_CHARSET = latin1
|
||||
mkinstalldirs = $(SHELL) $(toplevel_srcdir)/mkinstalldirs
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
WARN_CFLAGS = $(WARN_FLAGS) $(WERROR)
|
||||
|
||||
# -I/-D flags to pass when compiling.
|
||||
AM_CPPFLAGS = -I$(srcdir)/rt -I$(srcdir)/include/internal
|
||||
AM_CFLAGS = \
|
||||
-I $(srcdir)/../include \
|
||||
-I $(srcdir)/../libgcc \
|
||||
-I $(MULTIBUILDTOP)../../gcc/include $(PTH_CFLAGS)
|
||||
|
||||
toolexeclib_LTLIBRARIES = libhsail-rt.la
|
||||
runtime_files = \
|
||||
rt/arithmetic.c \
|
||||
rt/atomics.c \
|
||||
rt/bitstring.c \
|
||||
rt/fbarrier.c \
|
||||
rt/fp16.c \
|
||||
rt/misc.c \
|
||||
rt/multimedia.c \
|
||||
rt/queue.c \
|
||||
rt/sat_arithmetic.c \
|
||||
rt/segment.c \
|
||||
rt/workitems.c \
|
||||
rt/fibers.c
|
||||
|
||||
libhsail_rt_la_SOURCES = $(runtime_files)
|
||||
libhsail_rt_la_LDFLAGS = -rpath '$(libdir)'
|
||||
|
||||
# Work around what appears to be a GNU make bug handling MAKEFLAGS
|
||||
# values defined in terms of make variables, as is the case for CC and
|
||||
# friends when we are called from the top level Makefile.
|
||||
AM_MAKEFLAGS = \
|
||||
"AR_FLAGS=$(AR_FLAGS)" \
|
||||
"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
|
||||
"CFLAGS=$(CFLAGS)" \
|
||||
"CXXFLAGS=$(CXXFLAGS)" \
|
||||
"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
|
||||
"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
|
||||
"INSTALL=$(INSTALL)" \
|
||||
"INSTALL_DATA=$(INSTALL_DATA)" \
|
||||
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
|
||||
"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
|
||||
"JC1FLAGS=$(JC1FLAGS)" \
|
||||
"LDFLAGS=$(LDFLAGS)" \
|
||||
"LIBCFLAGS=$(LIBCFLAGS)" \
|
||||
"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
|
||||
"MAKE=$(MAKE)" \
|
||||
"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
|
||||
"PICFLAG=$(PICFLAG)" \
|
||||
"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
|
||||
"SHELL=$(SHELL)" \
|
||||
"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
|
||||
"exec_prefix=$(exec_prefix)" \
|
||||
"infodir=$(infodir)" \
|
||||
"libdir=$(libdir)" \
|
||||
"prefix=$(prefix)" \
|
||||
"includedir=$(includedir)" \
|
||||
"AR=$(AR)" \
|
||||
"AS=$(AS)" \
|
||||
"LD=$(LD)" \
|
||||
"LIBCFLAGS=$(LIBCFLAGS)" \
|
||||
"NM=$(NM)" \
|
||||
"PICFLAG=$(PICFLAG)" \
|
||||
"RANLIB=$(RANLIB)" \
|
||||
"DESTDIR=$(DESTDIR)"
|
||||
|
||||
MAKEOVERRIDES =
|
||||
all: target-config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
am--refresh: Makefile
|
||||
@:
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
|
||||
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
echo ' $(SHELL) ./config.status'; \
|
||||
$(SHELL) ./config.status;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
$(SHELL) ./config.status --recheck
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
$(am__cd) $(srcdir) && $(AUTOCONF)
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
target-config.h: stamp-h1
|
||||
@if test ! -f $@; then rm -f stamp-h1; else :; fi
|
||||
@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
|
||||
|
||||
stamp-h1: $(srcdir)/target-config.h.in $(top_builddir)/config.status
|
||||
@rm -f stamp-h1
|
||||
cd $(top_builddir) && $(SHELL) ./config.status target-config.h
|
||||
$(srcdir)/target-config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
|
||||
rm -f stamp-h1
|
||||
touch $@
|
||||
|
||||
distclean-hdr:
|
||||
-rm -f target-config.h stamp-h1
|
||||
install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
@list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
list2="$$list2 $$p"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { \
|
||||
echo " $(MKDIR_P) '$(DESTDIR)$(toolexeclibdir)'"; \
|
||||
$(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)" || exit 1; \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(toolexeclibdir)"; \
|
||||
}
|
||||
|
||||
uninstall-toolexeclibLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-toolexeclibLTLIBRARIES:
|
||||
-test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES)
|
||||
@list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
rt/$(am__dirstamp):
|
||||
@$(MKDIR_P) rt
|
||||
@: > rt/$(am__dirstamp)
|
||||
rt/$(DEPDIR)/$(am__dirstamp):
|
||||
@$(MKDIR_P) rt/$(DEPDIR)
|
||||
@: > rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/arithmetic.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/atomics.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/bitstring.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/fbarrier.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/fp16.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/misc.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/multimedia.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/queue.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/sat_arithmetic.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/segment.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/workitems.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
rt/fibers.lo: rt/$(am__dirstamp) rt/$(DEPDIR)/$(am__dirstamp)
|
||||
libhsail-rt.la: $(libhsail_rt_la_OBJECTS) $(libhsail_rt_la_DEPENDENCIES) $(EXTRA_libhsail_rt_la_DEPENDENCIES)
|
||||
$(libhsail_rt_la_LINK) -rpath $(toolexeclibdir) $(libhsail_rt_la_OBJECTS) $(libhsail_rt_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
-rm -f rt/arithmetic.$(OBJEXT)
|
||||
-rm -f rt/arithmetic.lo
|
||||
-rm -f rt/atomics.$(OBJEXT)
|
||||
-rm -f rt/atomics.lo
|
||||
-rm -f rt/bitstring.$(OBJEXT)
|
||||
-rm -f rt/bitstring.lo
|
||||
-rm -f rt/fbarrier.$(OBJEXT)
|
||||
-rm -f rt/fbarrier.lo
|
||||
-rm -f rt/fibers.$(OBJEXT)
|
||||
-rm -f rt/fibers.lo
|
||||
-rm -f rt/fp16.$(OBJEXT)
|
||||
-rm -f rt/fp16.lo
|
||||
-rm -f rt/misc.$(OBJEXT)
|
||||
-rm -f rt/misc.lo
|
||||
-rm -f rt/multimedia.$(OBJEXT)
|
||||
-rm -f rt/multimedia.lo
|
||||
-rm -f rt/queue.$(OBJEXT)
|
||||
-rm -f rt/queue.lo
|
||||
-rm -f rt/sat_arithmetic.$(OBJEXT)
|
||||
-rm -f rt/sat_arithmetic.lo
|
||||
-rm -f rt/segment.$(OBJEXT)
|
||||
-rm -f rt/segment.lo
|
||||
-rm -f rt/workitems.$(OBJEXT)
|
||||
-rm -f rt/workitems.lo
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/arithmetic.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/atomics.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/bitstring.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/fbarrier.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/fibers.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/fp16.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/misc.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/multimedia.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/queue.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/sat_arithmetic.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/segment.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@rt/$(DEPDIR)/workitems.Plo@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
|
||||
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
-rm -rf rt/.libs rt/_libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool config.lt
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) target-config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) target-config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) target-config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) target-config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LTLIBRARIES) target-config.h
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(toolexeclibdir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
if test -z '$(STRIP)'; then \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
install; \
|
||||
else \
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
|
||||
fi
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
-rm -f rt/$(DEPDIR)/$(am__dirstamp)
|
||||
-rm -f rt/$(am__dirstamp)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf rt/$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-hdr distclean-libtool distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am:
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am: install-toolexeclibLTLIBRARIES
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man:
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -rf rt/$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-toolexeclibLTLIBRARIES
|
||||
|
||||
.MAKE: all install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
|
||||
clean-generic clean-libtool clean-toolexeclibLTLIBRARIES ctags \
|
||||
distclean distclean-compile distclean-generic distclean-hdr \
|
||||
distclean-libtool distclean-tags dvi dvi-am html html-am info \
|
||||
info-am install install-am install-data install-data-am \
|
||||
install-dvi install-dvi-am install-exec install-exec-am \
|
||||
install-html install-html-am install-info install-info-am \
|
||||
install-man install-pdf install-pdf-am install-ps \
|
||||
install-ps-am install-strip install-toolexeclibLTLIBRARIES \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags uninstall uninstall-am uninstall-toolexeclibLTLIBRARIES
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
4
libhsail-rt/README
Normal file
4
libhsail-rt/README
Normal file
|
@ -0,0 +1,4 @@
|
|||
Run autoconf2.64 && automake-1.11 to regenerate the buildfiles.
|
||||
You might need to manually tweak the minor automake version number
|
||||
in configure.ac and aclocal.m4 (search for 1.11.6) in case your
|
||||
local 1.11 minor version doesn't match.
|
978
libhsail-rt/aclocal.m4
vendored
Normal file
978
libhsail-rt/aclocal.m4
vendored
Normal file
|
@ -0,0 +1,978 @@
|
|||
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
|
||||
[m4_warning([this file was generated for autoconf 2.64.
|
||||
You have another version of autoconf. It may work, but is not guaranteed to.
|
||||
If you have problems, you may need to regenerate the build system entirely.
|
||||
To do so, use the procedure documented by the package, typically `autoreconf'.])])
|
||||
|
||||
# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_AUTOMAKE_VERSION(VERSION)
|
||||
# ----------------------------
|
||||
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
||||
# generated from the m4 files accompanying Automake X.Y.
|
||||
# (This private macro should not be called outside this file.)
|
||||
AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||
[am__api_version='1.11'
|
||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||
dnl require some minimum version. Point them to the right macro.
|
||||
m4_if([$1], [1.11.6], [],
|
||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||
])
|
||||
|
||||
# _AM_AUTOCONF_VERSION(VERSION)
|
||||
# -----------------------------
|
||||
# aclocal traces this macro to find the Autoconf version.
|
||||
# This is a private macro too. Using m4_define simplifies
|
||||
# the logic in aclocal, which can simply ignore this definition.
|
||||
m4_define([_AM_AUTOCONF_VERSION], [])
|
||||
|
||||
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
||||
# -------------------------------
|
||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.11.6])dnl
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
|
||||
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
|
||||
#
|
||||
# Of course, Automake must honor this variable whenever it calls a
|
||||
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||
# depending on how configure is run. This is pretty annoying, since
|
||||
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||
# source directory, any form will work fine, but in subdirectories a
|
||||
# relative path needs to be adjusted first.
|
||||
#
|
||||
# $ac_aux_dir/missing
|
||||
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||
# $top_srcdir/$ac_aux_dir/missing
|
||||
# fails if $ac_aux_dir is absolute,
|
||||
# fails when called from a subdirectory in a VPATH build with
|
||||
# a relative $ac_aux_dir
|
||||
#
|
||||
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||
# harmless because $srcdir is `.', but things will broke when you
|
||||
# start a VPATH build or use an absolute $srcdir.
|
||||
#
|
||||
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||
# and then we would define $MISSING as
|
||||
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# This will work as long as MISSING is not called from configure, because
|
||||
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||
# However there are other variables, like CC, which are often used in
|
||||
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||
#
|
||||
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||
# configured tree to be moved without reconfiguration.
|
||||
|
||||
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||
[dnl Rely on autoconf to set up CDPATH properly.
|
||||
AC_PREREQ([2.50])dnl
|
||||
# expand $ac_aux_dir to an absolute path
|
||||
am_aux_dir=`cd $ac_aux_dir && pwd`
|
||||
])
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 9
|
||||
|
||||
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||
# -------------------------------------
|
||||
# Define a conditional.
|
||||
AC_DEFUN([AM_CONDITIONAL],
|
||||
[AC_PREREQ(2.52)dnl
|
||||
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||
AC_SUBST([$1_TRUE])dnl
|
||||
AC_SUBST([$1_FALSE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
|
||||
m4_define([_AM_COND_VALUE_$1], [$2])dnl
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 10
|
||||
|
||||
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
|
||||
# written in clear, in which case automake, when reading aclocal.m4,
|
||||
# will think it sees a *use*, and therefore will trigger all it's
|
||||
# C support machinery. Also note that it means that autoscan, seeing
|
||||
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
|
||||
|
||||
|
||||
# _AM_DEPENDENCIES(NAME)
|
||||
# ----------------------
|
||||
# See how the compiler implements dependency checking.
|
||||
# NAME is "CC", "CXX", "GCJ", or "OBJC".
|
||||
# We try a few techniques and use that to set a single cache variable.
|
||||
#
|
||||
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
|
||||
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
|
||||
# dependency, and given that the user is not expected to run this macro,
|
||||
# just rely on AC_PROG_CC.
|
||||
AC_DEFUN([_AM_DEPENDENCIES],
|
||||
[AC_REQUIRE([AM_SET_DEPDIR])dnl
|
||||
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
|
||||
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
|
||||
AC_REQUIRE([AM_DEP_TRACK])dnl
|
||||
|
||||
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
|
||||
[$1], CXX, [depcc="$CXX" am_compiler_list=],
|
||||
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
|
||||
[$1], UPC, [depcc="$UPC" am_compiler_list=],
|
||||
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
|
||||
[depcc="$$1" am_compiler_list=])
|
||||
|
||||
AC_CACHE_CHECK([dependency style of $depcc],
|
||||
[am_cv_$1_dependencies_compiler_type],
|
||||
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
|
||||
# We make a subdir and do the tests there. Otherwise we can end up
|
||||
# making bogus files that we don't know about and never remove. For
|
||||
# instance it was reported that on HP-UX the gcc test will end up
|
||||
# making a dummy file named `D' -- because `-MD' means `put the output
|
||||
# in D'.
|
||||
mkdir conftest.dir
|
||||
# Copy depcomp to subdir because otherwise we won't find it if we're
|
||||
# using a relative directory.
|
||||
cp "$am_depcomp" conftest.dir
|
||||
cd conftest.dir
|
||||
# We will build objects and dependencies in a subdirectory because
|
||||
# it helps to detect inapplicable dependency modes. For instance
|
||||
# both Tru64's cc and ICC support -MD to output dependencies as a
|
||||
# side effect of compilation, but ICC will put the dependencies in
|
||||
# the current directory while Tru64 will put them in the object
|
||||
# directory.
|
||||
mkdir sub
|
||||
|
||||
am_cv_$1_dependencies_compiler_type=none
|
||||
if test "$am_compiler_list" = ""; then
|
||||
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
|
||||
fi
|
||||
am__universal=false
|
||||
m4_case([$1], [CC],
|
||||
[case " $depcc " in #(
|
||||
*\ -arch\ *\ -arch\ *) am__universal=true ;;
|
||||
esac],
|
||||
[CXX],
|
||||
[case " $depcc " in #(
|
||||
*\ -arch\ *\ -arch\ *) am__universal=true ;;
|
||||
esac])
|
||||
|
||||
for depmode in $am_compiler_list; do
|
||||
# Setup a source with many dependencies, because some compilers
|
||||
# like to wrap large dependency lists on column 80 (with \), and
|
||||
# we should not choose a depcomp mode which is confused by this.
|
||||
#
|
||||
# We need to recreate these files for each test, as the compiler may
|
||||
# overwrite some of them when testing with obscure command lines.
|
||||
# This happens at least with the AIX C compiler.
|
||||
: > sub/conftest.c
|
||||
for i in 1 2 3 4 5 6; do
|
||||
echo '#include "conftst'$i'.h"' >> sub/conftest.c
|
||||
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
|
||||
# Solaris 8's {/usr,}/bin/sh.
|
||||
touch sub/conftst$i.h
|
||||
done
|
||||
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
|
||||
|
||||
# We check with `-c' and `-o' for the sake of the "dashmstdout"
|
||||
# mode. It turns out that the SunPro C++ compiler does not properly
|
||||
# handle `-M -o', and we need to detect this. Also, some Intel
|
||||
# versions had trouble with output in subdirs
|
||||
am__obj=sub/conftest.${OBJEXT-o}
|
||||
am__minus_obj="-o $am__obj"
|
||||
case $depmode in
|
||||
gcc)
|
||||
# This depmode causes a compiler race in universal mode.
|
||||
test "$am__universal" = false || continue
|
||||
;;
|
||||
nosideeffect)
|
||||
# after this tag, mechanisms are not by side-effect, so they'll
|
||||
# only be used when explicitly requested
|
||||
if test "x$enable_dependency_tracking" = xyes; then
|
||||
continue
|
||||
else
|
||||
break
|
||||
fi
|
||||
;;
|
||||
msvisualcpp | msvcmsys)
|
||||
# This compiler won't grok `-c -o', but also, the minuso test has
|
||||
# not run yet. These depmodes are late enough in the game, and
|
||||
# so weak that their functioning should not be impacted.
|
||||
am__obj=conftest.${OBJEXT-o}
|
||||
am__minus_obj=
|
||||
;;
|
||||
none) break ;;
|
||||
esac
|
||||
if depmode=$depmode \
|
||||
source=sub/conftest.c object=$am__obj \
|
||||
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
|
||||
$SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
|
||||
>/dev/null 2>conftest.err &&
|
||||
grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
|
||||
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
|
||||
grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
|
||||
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
|
||||
# icc doesn't choke on unknown options, it will just issue warnings
|
||||
# or remarks (even with -Werror). So we grep stderr for any message
|
||||
# that says an option was ignored or not supported.
|
||||
# When given -MP, icc 7.0 and 7.1 complain thusly:
|
||||
# icc: Command line warning: ignoring option '-M'; no argument required
|
||||
# The diagnosis changed in icc 8.0:
|
||||
# icc: Command line remark: option '-MP' not supported
|
||||
if (grep 'ignoring option' conftest.err ||
|
||||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
|
||||
am_cv_$1_dependencies_compiler_type=$depmode
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
cd ..
|
||||
rm -rf conftest.dir
|
||||
else
|
||||
am_cv_$1_dependencies_compiler_type=none
|
||||
fi
|
||||
])
|
||||
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
|
||||
AM_CONDITIONAL([am__fastdep$1], [
|
||||
test "x$enable_dependency_tracking" != xno \
|
||||
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
|
||||
])
|
||||
|
||||
|
||||
# AM_SET_DEPDIR
|
||||
# -------------
|
||||
# Choose a directory name for dependency files.
|
||||
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
|
||||
AC_DEFUN([AM_SET_DEPDIR],
|
||||
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
|
||||
])
|
||||
|
||||
|
||||
# AM_DEP_TRACK
|
||||
# ------------
|
||||
AC_DEFUN([AM_DEP_TRACK],
|
||||
[AC_ARG_ENABLE(dependency-tracking,
|
||||
[ --disable-dependency-tracking speeds up one-time build
|
||||
--enable-dependency-tracking do not reject slow dependency extractors])
|
||||
if test "x$enable_dependency_tracking" != xno; then
|
||||
am_depcomp="$ac_aux_dir/depcomp"
|
||||
AMDEPBACKSLASH='\'
|
||||
fi
|
||||
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
|
||||
AC_SUBST([AMDEPBACKSLASH])dnl
|
||||
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
|
||||
])
|
||||
|
||||
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
#serial 5
|
||||
|
||||
# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
# ------------------------------
|
||||
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[{
|
||||
# Autoconf 2.62 quotes --file arguments for eval, but not when files
|
||||
# are listed without --file. Let's play safe and only enable the eval
|
||||
# if we detect the quoting.
|
||||
case $CONFIG_FILES in
|
||||
*\'*) eval set x "$CONFIG_FILES" ;;
|
||||
*) set x $CONFIG_FILES ;;
|
||||
esac
|
||||
shift
|
||||
for mf
|
||||
do
|
||||
# Strip MF so we end up with the name of the file.
|
||||
mf=`echo "$mf" | sed -e 's/:.*$//'`
|
||||
# Check whether this is an Automake generated Makefile or not.
|
||||
# We used to match only the files named `Makefile.in', but
|
||||
# some people rename them; so instead we look at the file content.
|
||||
# Grep'ing the first line is not enough: some people post-process
|
||||
# each Makefile.in and add a new line on top of each file to say so.
|
||||
# Grep'ing the whole file is not good either: AIX grep has a line
|
||||
# limit of 2048, but all sed's we know have understand at least 4000.
|
||||
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
|
||||
dirpart=`AS_DIRNAME("$mf")`
|
||||
else
|
||||
continue
|
||||
fi
|
||||
# Extract the definition of DEPDIR, am__include, and am__quote
|
||||
# from the Makefile without running `make'.
|
||||
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
|
||||
test -z "$DEPDIR" && continue
|
||||
am__include=`sed -n 's/^am__include = //p' < "$mf"`
|
||||
test -z "am__include" && continue
|
||||
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
|
||||
# When using ansi2knr, U may be empty or an underscore; expand it
|
||||
U=`sed -n 's/^U = //p' < "$mf"`
|
||||
# Find all dependency output files, they are included files with
|
||||
# $(DEPDIR) in their names. We invoke sed twice because it is the
|
||||
# simplest approach to changing $(DEPDIR) to its actual value in the
|
||||
# expansion.
|
||||
for file in `sed -n "
|
||||
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
|
||||
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
|
||||
# Make sure the directory exists.
|
||||
test -f "$dirpart/$file" && continue
|
||||
fdir=`AS_DIRNAME(["$file"])`
|
||||
AS_MKDIR_P([$dirpart/$fdir])
|
||||
# echo "creating $dirpart/$file"
|
||||
echo '# dummy' > "$dirpart/$file"
|
||||
done
|
||||
done
|
||||
}
|
||||
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
|
||||
|
||||
# AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
# -----------------------------
|
||||
# This macro should only be invoked once -- use via AC_REQUIRE.
|
||||
#
|
||||
# This code is only required when automatic dependency tracking
|
||||
# is enabled. FIXME. This creates each `.P' file that we will
|
||||
# need in order to bootstrap the dependency handling code.
|
||||
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[AC_CONFIG_COMMANDS([depfiles],
|
||||
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
|
||||
])
|
||||
|
||||
# Do all the work for Automake. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 16
|
||||
|
||||
# This macro actually does too much. Some checks are only needed if
|
||||
# your package does certain things. But this isn't really a big deal.
|
||||
|
||||
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
|
||||
# AM_INIT_AUTOMAKE([OPTIONS])
|
||||
# -----------------------------------------------
|
||||
# The call with PACKAGE and VERSION arguments is the old style
|
||||
# call (pre autoconf-2.50), which is being phased out. PACKAGE
|
||||
# and VERSION should now be passed to AC_INIT and removed from
|
||||
# the call to AM_INIT_AUTOMAKE.
|
||||
# We support both call styles for the transition. After
|
||||
# the next Automake release, Autoconf can make the AC_INIT
|
||||
# arguments mandatory, and then we can depend on a new Autoconf
|
||||
# release and drop the old call support.
|
||||
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||
[AC_PREREQ([2.62])dnl
|
||||
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
||||
dnl the ones we care about.
|
||||
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
||||
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
||||
AC_REQUIRE([AC_PROG_INSTALL])dnl
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`"; then
|
||||
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
|
||||
# is not polluted with repeated "-I."
|
||||
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
|
||||
# test to see if srcdir already configured
|
||||
if test -f $srcdir/config.status; then
|
||||
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||
fi
|
||||
fi
|
||||
|
||||
# test whether we have cygpath
|
||||
if test -z "$CYGPATH_W"; then
|
||||
if (cygpath --version) >/dev/null 2>/dev/null; then
|
||||
CYGPATH_W='cygpath -w'
|
||||
else
|
||||
CYGPATH_W=echo
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([CYGPATH_W])
|
||||
|
||||
# Define the identity of the package.
|
||||
dnl Distinguish between old-style and new-style calls.
|
||||
m4_ifval([$2],
|
||||
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||
AC_SUBST([PACKAGE], [$1])dnl
|
||||
AC_SUBST([VERSION], [$2])],
|
||||
[_AM_SET_OPTIONS([$1])dnl
|
||||
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
|
||||
m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
|
||||
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
|
||||
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
||||
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
|
||||
|
||||
_AM_IF_OPTION([no-define],,
|
||||
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
|
||||
|
||||
# Some tools Automake needs.
|
||||
AC_REQUIRE([AM_SANITY_CHECK])dnl
|
||||
AC_REQUIRE([AC_ARG_PROGRAM])dnl
|
||||
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
|
||||
AM_MISSING_PROG(AUTOCONF, autoconf)
|
||||
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
|
||||
AM_MISSING_PROG(AUTOHEADER, autoheader)
|
||||
AM_MISSING_PROG(MAKEINFO, makeinfo)
|
||||
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
|
||||
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
|
||||
# We need awk for the "check" target. The system "awk" is bad on
|
||||
# some platforms.
|
||||
AC_REQUIRE([AC_PROG_AWK])dnl
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
||||
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
|
||||
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
|
||||
[_AM_PROG_TAR([v7])])])
|
||||
_AM_IF_OPTION([no-dependencies],,
|
||||
[AC_PROVIDE_IFELSE([AC_PROG_CC],
|
||||
[_AM_DEPENDENCIES(CC)],
|
||||
[define([AC_PROG_CC],
|
||||
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_CXX],
|
||||
[_AM_DEPENDENCIES(CXX)],
|
||||
[define([AC_PROG_CXX],
|
||||
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
|
||||
[_AM_DEPENDENCIES(OBJC)],
|
||||
[define([AC_PROG_OBJC],
|
||||
defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
|
||||
])
|
||||
_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
|
||||
dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
|
||||
dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
|
||||
dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
|
||||
AC_CONFIG_COMMANDS_PRE(dnl
|
||||
[m4_provide_if([_AM_COMPILER_EXEEXT],
|
||||
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
|
||||
])
|
||||
|
||||
dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
|
||||
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
|
||||
dnl mangled by Autoconf and run in a shell conditional statement.
|
||||
m4_define([_AC_COMPILER_EXEEXT],
|
||||
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
|
||||
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp files are numbered to have different names.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[# Compute $1's index in $config_headers.
|
||||
_am_arg=$1
|
||||
_am_stamp_count=1
|
||||
for _am_header in $config_headers :; do
|
||||
case $_am_header in
|
||||
$_am_arg | $_am_arg:* )
|
||||
break ;;
|
||||
* )
|
||||
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
|
||||
esac
|
||||
done
|
||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_SH
|
||||
# ------------------
|
||||
# Define $install_sh.
|
||||
AC_DEFUN([AM_PROG_INSTALL_SH],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
if test x"${install_sh}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
|
||||
*)
|
||||
install_sh="\${SHELL} $am_aux_dir/install-sh"
|
||||
esac
|
||||
fi
|
||||
AC_SUBST(install_sh)])
|
||||
|
||||
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
|
||||
# From Jim Meyering
|
||||
|
||||
# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 5
|
||||
|
||||
# AM_MAINTAINER_MODE([DEFAULT-MODE])
|
||||
# ----------------------------------
|
||||
# Control maintainer-specific portions of Makefiles.
|
||||
# Default is to disable them, unless `enable' is passed literally.
|
||||
# For symmetry, `disable' may be passed as well. Anyway, the user
|
||||
# can override the default with the --enable/--disable switch.
|
||||
AC_DEFUN([AM_MAINTAINER_MODE],
|
||||
[m4_case(m4_default([$1], [disable]),
|
||||
[enable], [m4_define([am_maintainer_other], [disable])],
|
||||
[disable], [m4_define([am_maintainer_other], [enable])],
|
||||
[m4_define([am_maintainer_other], [enable])
|
||||
m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
|
||||
AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
|
||||
dnl maintainer-mode's default is 'disable' unless 'enable' is passed
|
||||
AC_ARG_ENABLE([maintainer-mode],
|
||||
[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
|
||||
(and sometimes confusing) to the casual installer],
|
||||
[USE_MAINTAINER_MODE=$enableval],
|
||||
[USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
|
||||
AC_MSG_RESULT([$USE_MAINTAINER_MODE])
|
||||
AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
|
||||
MAINT=$MAINTAINER_MODE_TRUE
|
||||
AC_SUBST([MAINT])dnl
|
||||
]
|
||||
)
|
||||
|
||||
AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
|
||||
|
||||
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 4
|
||||
|
||||
# AM_MAKE_INCLUDE()
|
||||
# -----------------
|
||||
# Check to see how make treats includes.
|
||||
AC_DEFUN([AM_MAKE_INCLUDE],
|
||||
[am_make=${MAKE-make}
|
||||
cat > confinc << 'END'
|
||||
am__doit:
|
||||
@echo this is the am__doit target
|
||||
.PHONY: am__doit
|
||||
END
|
||||
# If we don't find an include directive, just comment out the code.
|
||||
AC_MSG_CHECKING([for style of include used by $am_make])
|
||||
am__include="#"
|
||||
am__quote=
|
||||
_am_result=none
|
||||
# First try GNU make style include.
|
||||
echo "include confinc" > confmf
|
||||
# Ignore all kinds of additional output from `make'.
|
||||
case `$am_make -s -f confmf 2> /dev/null` in #(
|
||||
*the\ am__doit\ target*)
|
||||
am__include=include
|
||||
am__quote=
|
||||
_am_result=GNU
|
||||
;;
|
||||
esac
|
||||
# Now try BSD make style include.
|
||||
if test "$am__include" = "#"; then
|
||||
echo '.include "confinc"' > confmf
|
||||
case `$am_make -s -f confmf 2> /dev/null` in #(
|
||||
*the\ am__doit\ target*)
|
||||
am__include=.include
|
||||
am__quote="\""
|
||||
_am_result=BSD
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
AC_SUBST([am__include])
|
||||
AC_SUBST([am__quote])
|
||||
AC_MSG_RESULT([$_am_result])
|
||||
rm -f confinc confmf
|
||||
])
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 6
|
||||
|
||||
# AM_MISSING_PROG(NAME, PROGRAM)
|
||||
# ------------------------------
|
||||
AC_DEFUN([AM_MISSING_PROG],
|
||||
[AC_REQUIRE([AM_MISSING_HAS_RUN])
|
||||
$1=${$1-"${am_missing_run}$2"}
|
||||
AC_SUBST($1)])
|
||||
|
||||
|
||||
# AM_MISSING_HAS_RUN
|
||||
# ------------------
|
||||
# Define MISSING if not defined so far and test if it supports --run.
|
||||
# If it does, set am_missing_run to use it, otherwise, to nothing.
|
||||
AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([missing])dnl
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --run true"; then
|
||||
am_missing_run="$MISSING --run "
|
||||
else
|
||||
am_missing_run=
|
||||
AC_MSG_WARN([`missing' script is too old or missing])
|
||||
fi
|
||||
])
|
||||
|
||||
# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_MKDIR_P
|
||||
# ---------------
|
||||
# Check for `mkdir -p'.
|
||||
AC_DEFUN([AM_PROG_MKDIR_P],
|
||||
[AC_PREREQ([2.60])dnl
|
||||
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
|
||||
dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
|
||||
dnl while keeping a definition of mkdir_p for backward compatibility.
|
||||
dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
|
||||
dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
|
||||
dnl Makefile.ins that do not define MKDIR_P, so we do our own
|
||||
dnl adjustment using top_builddir (which is defined more often than
|
||||
dnl MKDIR_P).
|
||||
AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
|
||||
case $mkdir_p in
|
||||
[[\\/$]]* | ?:[[\\/]]*) ;;
|
||||
*/*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
|
||||
esac
|
||||
])
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 4
|
||||
|
||||
# _AM_MANGLE_OPTION(NAME)
|
||||
# -----------------------
|
||||
AC_DEFUN([_AM_MANGLE_OPTION],
|
||||
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
# _AM_SET_OPTION(NAME)
|
||||
# ------------------------------
|
||||
# Set option NAME. Presently that only means defining a flag for this option.
|
||||
AC_DEFUN([_AM_SET_OPTION],
|
||||
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
|
||||
|
||||
# _AM_SET_OPTIONS(OPTIONS)
|
||||
# ----------------------------------
|
||||
# OPTIONS is a space-separated list of Automake options.
|
||||
AC_DEFUN([_AM_SET_OPTIONS],
|
||||
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
|
||||
|
||||
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
|
||||
# -------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
AC_DEFUN([_AM_IF_OPTION],
|
||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||
|
||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 5
|
||||
|
||||
# AM_SANITY_CHECK
|
||||
# ---------------
|
||||
AC_DEFUN([AM_SANITY_CHECK],
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Just in case
|
||||
sleep 1
|
||||
echo timestamp > conftest.file
|
||||
# Reject unsafe characters in $srcdir or the absolute working directory
|
||||
# name. Accept space and tab only in the latter.
|
||||
am_lf='
|
||||
'
|
||||
case `pwd` in
|
||||
*[[\\\"\#\$\&\'\`$am_lf]]*)
|
||||
AC_MSG_ERROR([unsafe absolute working directory name]);;
|
||||
esac
|
||||
case $srcdir in
|
||||
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
|
||||
AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
|
||||
esac
|
||||
|
||||
# Do `set' in a subshell so we don't clobber the current shell's
|
||||
# arguments. Must try -L first in case configure is actually a
|
||||
# symlink; some systems play weird games with the mod time of symlinks
|
||||
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||
# directory).
|
||||
if (
|
||||
set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
|
||||
if test "$[*]" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t "$srcdir/configure" conftest.file`
|
||||
fi
|
||||
rm -f conftest.file
|
||||
if test "$[*]" != "X $srcdir/configure conftest.file" \
|
||||
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
|
||||
|
||||
# If neither matched, then we have a broken ls. This can happen
|
||||
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||
# broken ls alias from the environment. This has actually
|
||||
# happened. Such a system could not be considered "sane".
|
||||
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||
alias in your environment])
|
||||
fi
|
||||
|
||||
test "$[2]" = conftest.file
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)])
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_STRIP
|
||||
# ---------------------
|
||||
# One issue with vendor `install' (even GNU) is that you can't
|
||||
# specify the program used to strip binaries. This is especially
|
||||
# annoying in cross-compiling environments, where the build's strip
|
||||
# is unlikely to handle the host's binaries.
|
||||
# Fortunately install-sh will honor a STRIPPROG variable, so we
|
||||
# always use install-sh in `make install-strip', and initialize
|
||||
# STRIPPROG with the value of the STRIP variable (set by the user).
|
||||
AC_DEFUN([AM_PROG_INSTALL_STRIP],
|
||||
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
# Installed binaries are usually stripped using `strip' when the user
|
||||
# run `make install-strip'. However `strip' might not be the right
|
||||
# tool to use in cross-compilation environments, therefore Automake
|
||||
# will honor the `STRIP' environment variable to overrule this program.
|
||||
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
|
||||
if test "$cross_compiling" != no; then
|
||||
AC_CHECK_TOOL([STRIP], [strip], :)
|
||||
fi
|
||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||
|
||||
# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 2
|
||||
|
||||
# _AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
|
||||
# This macro is traced by Automake.
|
||||
AC_DEFUN([_AM_SUBST_NOTMAKE])
|
||||
|
||||
# AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Public sister of _AM_SUBST_NOTMAKE.
|
||||
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
# Check how to create a tarball. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 2
|
||||
|
||||
# _AM_PROG_TAR(FORMAT)
|
||||
# --------------------
|
||||
# Check how to create a tarball in format FORMAT.
|
||||
# FORMAT should be one of `v7', `ustar', or `pax'.
|
||||
#
|
||||
# Substitute a variable $(am__tar) that is a command
|
||||
# writing to stdout a FORMAT-tarball containing the directory
|
||||
# $tardir.
|
||||
# tardir=directory && $(am__tar) > result.tar
|
||||
#
|
||||
# Substitute a variable $(am__untar) that extract such
|
||||
# a tarball read from stdin.
|
||||
# $(am__untar) < result.tar
|
||||
AC_DEFUN([_AM_PROG_TAR],
|
||||
[# Always define AMTAR for backward compatibility.
|
||||
AM_MISSING_PROG([AMTAR], [tar])
|
||||
m4_if([$1], [v7],
|
||||
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
|
||||
[m4_case([$1], [ustar],, [pax],,
|
||||
[m4_fatal([Unknown tar format])])
|
||||
AC_MSG_CHECKING([how to create a $1 tar archive])
|
||||
# Loop over all known methods to create a tar archive until one works.
|
||||
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
|
||||
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
|
||||
# Do not fold the above two line into one, because Tru64 sh and
|
||||
# Solaris sh will not grok spaces in the rhs of `-'.
|
||||
for _am_tool in $_am_tools
|
||||
do
|
||||
case $_am_tool in
|
||||
gnutar)
|
||||
for _am_tar in tar gnutar gtar;
|
||||
do
|
||||
AM_RUN_LOG([$_am_tar --version]) && break
|
||||
done
|
||||
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
|
||||
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
|
||||
am__untar="$_am_tar -xf -"
|
||||
;;
|
||||
plaintar)
|
||||
# Must skip GNU tar: if it does not support --format= it doesn't create
|
||||
# ustar tarball either.
|
||||
(tar --version) >/dev/null 2>&1 && continue
|
||||
am__tar='tar chf - "$$tardir"'
|
||||
am__tar_='tar chf - "$tardir"'
|
||||
am__untar='tar xf -'
|
||||
;;
|
||||
pax)
|
||||
am__tar='pax -L -x $1 -w "$$tardir"'
|
||||
am__tar_='pax -L -x $1 -w "$tardir"'
|
||||
am__untar='pax -r'
|
||||
;;
|
||||
cpio)
|
||||
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
|
||||
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
|
||||
am__untar='cpio -i -H $1 -d'
|
||||
;;
|
||||
none)
|
||||
am__tar=false
|
||||
am__tar_=false
|
||||
am__untar=false
|
||||
;;
|
||||
esac
|
||||
|
||||
# If the value was cached, stop now. We just wanted to have am__tar
|
||||
# and am__untar set.
|
||||
test -n "${am_cv_prog_tar_$1}" && break
|
||||
|
||||
# tar/untar a dummy directory, and stop if the command works
|
||||
rm -rf conftest.dir
|
||||
mkdir conftest.dir
|
||||
echo GrepMe > conftest.dir/file
|
||||
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
|
||||
rm -rf conftest.dir
|
||||
if test -s conftest.tar; then
|
||||
AM_RUN_LOG([$am__untar <conftest.tar])
|
||||
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
|
||||
fi
|
||||
done
|
||||
rm -rf conftest.dir
|
||||
|
||||
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
|
||||
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
|
||||
AC_SUBST([am__tar])
|
||||
AC_SUBST([am__untar])
|
||||
]) # _AM_PROG_TAR
|
||||
|
||||
m4_include([../config/depstand.m4])
|
||||
m4_include([../config/lead-dot.m4])
|
||||
m4_include([../config/multi.m4])
|
||||
m4_include([../libtool.m4])
|
||||
m4_include([../ltoptions.m4])
|
||||
m4_include([../ltsugar.m4])
|
||||
m4_include([../ltversion.m4])
|
||||
m4_include([../lt~obsolete.m4])
|
217
libhsail-rt/config.h.in
Normal file
217
libhsail-rt/config.h.in
Normal file
|
@ -0,0 +1,217 @@
|
|||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
#undef AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
/* Define to 1 if you have the `acosl' function. */
|
||||
#undef HAVE_ACOSL
|
||||
|
||||
/* Define to 1 if you have the `asinl' function. */
|
||||
#undef HAVE_ASINL
|
||||
|
||||
/* Define to 1 if you have the `atan2l' function. */
|
||||
#undef HAVE_ATAN2L
|
||||
|
||||
/* Define to 1 if you have the `atanl' function. */
|
||||
#undef HAVE_ATANL
|
||||
|
||||
/* Define to 1 if you have the `cosl' function. */
|
||||
#undef HAVE_COSL
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `expl' function. */
|
||||
#undef HAVE_EXPL
|
||||
|
||||
/* Define to 1 if you have the `expm1l' function. */
|
||||
#undef HAVE_EXPM1L
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `ldexpl' function. */
|
||||
#undef HAVE_LDEXPL
|
||||
|
||||
/* Define to 1 if you have the <linux/ether.h> header file. */
|
||||
#undef HAVE_LINUX_ETHER_H
|
||||
|
||||
/* Define to 1 if you have the <linux/fs.h> header file. */
|
||||
#undef HAVE_LINUX_FS_H
|
||||
|
||||
/* Define to 1 if you have the <linux/reboot.h> header file. */
|
||||
#undef HAVE_LINUX_REBOOT_H
|
||||
|
||||
/* Define to 1 if you have the `log10l' function. */
|
||||
#undef HAVE_LOG10L
|
||||
|
||||
/* Define to 1 if you have the `log1pl' function. */
|
||||
#undef HAVE_LOG1PL
|
||||
|
||||
/* Define to 1 if you have the `logl' function. */
|
||||
#undef HAVE_LOGL
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/icmp6.h> header file. */
|
||||
#undef HAVE_NETINET_ICMP6_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/if_ether.h> header file. */
|
||||
#undef HAVE_NETINET_IF_ETHER_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in_syst.h> header file. */
|
||||
#undef HAVE_NETINET_IN_SYST_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/ip.h> header file. */
|
||||
#undef HAVE_NETINET_IP_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/ip_mroute.h> header file. */
|
||||
#undef HAVE_NETINET_IP_MROUTE_H
|
||||
|
||||
/* Define to 1 if you have the <netpacket/packet.h> header file. */
|
||||
#undef HAVE_NETPACKET_PACKET_H
|
||||
|
||||
/* Define to 1 if you have the <net/if_arp.h> header file. */
|
||||
#undef HAVE_NET_IF_ARP_H
|
||||
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#undef HAVE_NET_IF_H
|
||||
|
||||
/* Define to 1 if you have the <net/route.h> header file. */
|
||||
#undef HAVE_NET_ROUTE_H
|
||||
|
||||
/* Define to 1 if you have the <sched.h> header file. */
|
||||
#undef HAVE_SCHED_H
|
||||
|
||||
/* Define to 1 if you have the `sinl' function. */
|
||||
#undef HAVE_SINL
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if the compiler provides the __sync_bool_compare_and_swap
|
||||
function for uint32 */
|
||||
#undef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4
|
||||
|
||||
/* Define to 1 if the compiler provides the __sync_bool_compare_and_swap
|
||||
function for uint64 */
|
||||
#undef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8
|
||||
|
||||
/* Define to 1 if you have the <syscall.h> header file. */
|
||||
#undef HAVE_SYSCALL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#undef HAVE_SYS_EPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/file.h> header file. */
|
||||
#undef HAVE_SYS_FILE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/inotify.h> header file. */
|
||||
#undef HAVE_SYS_INOTIFY_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mount.h> header file. */
|
||||
#undef HAVE_SYS_MOUNT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/prctl.h> header file. */
|
||||
#undef HAVE_SYS_PRCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ptrace.h> header file. */
|
||||
#undef HAVE_SYS_PTRACE_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/statfs.h> header file. */
|
||||
#undef HAVE_SYS_STATFS_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/syscall.h> header file. */
|
||||
#undef HAVE_SYS_SYSCALL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/sysinfo.h> header file. */
|
||||
#undef HAVE_SYS_SYSINFO_H
|
||||
|
||||
/* Define to 1 if you have the <sys/timex.h> header file. */
|
||||
#undef HAVE_SYS_TIMEX_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/user.h> header file. */
|
||||
#undef HAVE_SYS_USER_H
|
||||
|
||||
/* Define to 1 if you have the <sys/utsname.h> header file. */
|
||||
#undef HAVE_SYS_UTSNAME_H
|
||||
|
||||
/* Define to 1 if you have the <sys/vfs.h> header file. */
|
||||
#undef HAVE_SYS_VFS_H
|
||||
|
||||
/* Define to 1 if you have the `tanl' function. */
|
||||
#undef HAVE_TANL
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the <utime.h> header file. */
|
||||
#undef HAVE_UTIME_H
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
# if defined __BIG_ENDIAN__
|
||||
# define WORDS_BIGENDIAN 1
|
||||
# endif
|
||||
#else
|
||||
# ifndef WORDS_BIGENDIAN
|
||||
# undef WORDS_BIGENDIAN
|
||||
# endif
|
||||
#endif
|
17016
libhsail-rt/configure
vendored
Normal file
17016
libhsail-rt/configure
vendored
Normal file
File diff suppressed because it is too large
Load diff
151
libhsail-rt/configure.ac
Normal file
151
libhsail-rt/configure.ac
Normal file
|
@ -0,0 +1,151 @@
|
|||
# Starting point copied from libcilkrts:
|
||||
#
|
||||
# @copyright
|
||||
# Copyright (C) 2011-2013, Intel Corporation
|
||||
# All rights reserved.
|
||||
#
|
||||
# @copyright
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Intel Corporation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# @copyright
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
|
||||
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
AC_INIT([phsa HSAIL runtime library], [1.0], [pekka.jaaskelainen@parmance.com])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_PREREQ([2.64])
|
||||
|
||||
# Needed to define ${target}. Needs to be very early to avoid annoying
|
||||
# warning about calling AC_ARG_PROGRAM before AC_CANONICAL_SYSTEM
|
||||
AC_CANONICAL_SYSTEM
|
||||
target_alias=${target_alias-$host_alias}
|
||||
AC_SUBST(target_alias)
|
||||
AM_INIT_AUTOMAKE([1.11.6 foreign no-dist])
|
||||
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
# AC_PROG_LIBTOOL
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
|
||||
if test "${multilib}" = "yes"; then
|
||||
multilib_arg="--enable-multilib"
|
||||
else
|
||||
multilib_arg=
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([for --enable-version-specific-runtime-libs])
|
||||
AC_ARG_ENABLE([version-specific-runtime-libs],
|
||||
AC_HELP_STRING([--enable-version-specific-runtime-libs],
|
||||
[Specify that runtime libraries should be installed in a compi
|
||||
ler-specific directory]),
|
||||
[case "$enableval" in
|
||||
yes) enable_version_specific_runtime_libs=yes ;;
|
||||
no) enable_version_specific_runtime_libs=no ;;
|
||||
*) AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs
|
||||
]);;
|
||||
esac],
|
||||
[enable_version_specific_runtime_libs=no])
|
||||
AC_MSG_RESULT($enable_version_specific_runtime_libs)
|
||||
|
||||
# Calculate toolexeclibdir
|
||||
# Also toolexecdir, though it's only used in toolexeclibdir
|
||||
case ${enable_version_specific_runtime_libs} in
|
||||
yes)
|
||||
# Need the gcc compiler version to know where to install libraries
|
||||
# and header files if --enable-version-specific-runtime-libs option
|
||||
# is selected.
|
||||
toolexecdir='$(libdir)/gcc/$(target_alias)'
|
||||
toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
|
||||
;;
|
||||
no)
|
||||
if test -n "$with_cross_host" &&
|
||||
test x"$with_cross_host" != x"no"; then
|
||||
# Install a library built with a cross compiler in tooldir, not libdir.
|
||||
toolexecdir='$(exec_prefix)/$(target_alias)'
|
||||
toolexeclibdir='$(toolexecdir)/lib'
|
||||
else
|
||||
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
|
||||
toolexeclibdir='$(libdir)'
|
||||
fi
|
||||
multi_os_directory=`$CC -print-multi-os-directory`
|
||||
case $multi_os_directory in
|
||||
.) ;; # Avoid trailing /.
|
||||
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Set config_dir based on the target. config_dir specifies where to get
|
||||
# target-specific files. The generic implementation is incomplete, but
|
||||
# contains information on what's needed
|
||||
case "${target}" in
|
||||
|
||||
x86_64-*-*)
|
||||
config_dir="x86"
|
||||
;;
|
||||
|
||||
i?86-*-*)
|
||||
config_dir="x86"
|
||||
;;
|
||||
|
||||
*)
|
||||
config_dir="generic"
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(config_dir)
|
||||
|
||||
# We have linker scripts for appropriate operating systems
|
||||
linux_linker_script=no
|
||||
case "${host}" in
|
||||
*-*-linux*)
|
||||
linux_linker_script=yes
|
||||
;;
|
||||
esac
|
||||
AM_CONDITIONAL(LINUX_LINKER_SCRIPT, test "$linux_linker_script" = "yes")
|
||||
|
||||
mac_linker_script=no
|
||||
case "${host}" in
|
||||
*-*-apple*)
|
||||
mac_linker_script=yes
|
||||
;;
|
||||
esac
|
||||
AM_CONDITIONAL(MAC_LINKER_SCRIPT, test "$mac_linker_script" = "yes")
|
||||
|
||||
AC_LIBTOOL_DLOPEN
|
||||
AM_PROG_LIBTOOL
|
||||
AC_SUBST(toolexecdir)
|
||||
AC_SUBST(toolexeclibdir)
|
||||
|
||||
AC_CONFIG_HEADER(target-config.h)
|
||||
|
||||
AC_CHECK_SIZEOF([int])
|
||||
AC_CHECK_SIZEOF([void*])
|
||||
|
||||
# Must be last
|
||||
AC_OUTPUT
|
99
libhsail-rt/include/internal/fibers.h
Normal file
99
libhsail-rt/include/internal/fibers.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/* fibers.h -- an extremely simple lightweight thread (fiber) implementation
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PHSA_RT_FIBERS_H
|
||||
#define PHSA_RT_FIBERS_H
|
||||
|
||||
#include <ucontext.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
/* Ready to run. */
|
||||
FIBER_STATUS_READY,
|
||||
/* Exited by calling fiber_thread_exit. */
|
||||
FIBER_STATUS_EXITED,
|
||||
/* Joined by the main thread. */
|
||||
FIBER_STATUS_JOINED
|
||||
} fiber_status_t;
|
||||
|
||||
/* A light weight thread (fiber). */
|
||||
struct fiber_s
|
||||
{
|
||||
ucontext_t context;
|
||||
volatile fiber_status_t status;
|
||||
struct fiber_s *next;
|
||||
struct fiber_s *prev;
|
||||
};
|
||||
|
||||
typedef struct fiber_s fiber_t;
|
||||
|
||||
typedef void (*fiber_function_t)(int, int);
|
||||
|
||||
/* Initializes the fiber with the start function given as the first
|
||||
argument, and the argument to pass to the start function,
|
||||
as the second. The allocated stack size is given as the last argument. */
|
||||
void
|
||||
fiber_init (fiber_t *fiber, fiber_function_t start_function, void *arg,
|
||||
size_t stack_size, size_t stack_align);
|
||||
|
||||
/* Terminates the fiber execution from within the fiber itself. */
|
||||
void
|
||||
fiber_exit ();
|
||||
|
||||
/* Blocks until the given fiber returns. Frees the resources allocated
|
||||
for the fiber. After join returns, the fiber itself can be deleted. */
|
||||
void
|
||||
fiber_join (fiber_t *fiber);
|
||||
|
||||
/* Co-operatively transfer execution turn to other fibers. */
|
||||
void
|
||||
fiber_yield ();
|
||||
|
||||
/* A multi-entry barrier. After the last fiber has reached the
|
||||
barrier, it is automatically re-initialized to the threshold. */
|
||||
typedef struct
|
||||
{
|
||||
/* The barrier participant count. */
|
||||
volatile size_t threshold;
|
||||
/* Number of fibers that have reached the barrier. */
|
||||
volatile size_t reached;
|
||||
/* Number of fibers that are waiting at the barrier. */
|
||||
volatile size_t waiting_count;
|
||||
} fiber_barrier_t;
|
||||
|
||||
/* Reach the given barrier. Blocks (co-operatively switches the execution
|
||||
fibers) until all other parties have reached it. Returns 0 only in case
|
||||
the calling fiber was the first one to return from the barrier. */
|
||||
size_t
|
||||
fiber_barrier_reach (fiber_barrier_t *barrier);
|
||||
|
||||
/* Initializes the given barrier. */
|
||||
void
|
||||
fiber_barrier_init (fiber_barrier_t *barrier, size_t threshold);
|
||||
|
||||
void *
|
||||
fiber_int_args_to_ptr (int arg0, int arg1);
|
||||
|
||||
#endif
|
60
libhsail-rt/include/internal/phsa-queue-interface.h
Normal file
60
libhsail-rt/include/internal/phsa-queue-interface.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* phsa_queue_interface.h -- Definition for a minimalistic generic in-memory
|
||||
representation of a user mode queue to be used with the phsa/gccbrig
|
||||
implementation.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PHSA_QUEUE_INTERFACE_H
|
||||
#define PHSA_QUEUE_INTERFACE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "hsa.h"
|
||||
|
||||
typedef __attribute__ ((aligned (64))) struct phsa_queue_s
|
||||
{
|
||||
/* An HSA Architectured Queue object. Must be in the beginning
|
||||
of the struct to enable direct pointer casting between hsa_queue_
|
||||
and phsa_queue_t. */
|
||||
hsa_queue_t hsa_queue;
|
||||
|
||||
volatile uint64_t write_index;
|
||||
volatile uint64_t read_index;
|
||||
|
||||
/* True if global mem addresses are 64b. */
|
||||
uint64_t is_ptr64 : 1;
|
||||
|
||||
} phsa_queue_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
94
libhsail-rt/include/internal/phsa-rt.h
Normal file
94
libhsail-rt/include/internal/phsa-rt.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/* phsa-rt.h -- Data structures and functions of the PHSA device side runtime
|
||||
scheduler, and HSAIL built-ins.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PHSA_RT_H
|
||||
#define PHSA_RT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "hsa.h"
|
||||
|
||||
#define PHSA_MAX_WG_SIZE 1024 * 10
|
||||
|
||||
/* Pointer type for the public facing kernel launcher function generated
|
||||
by gccbrig. This launches the actual kernel for all work groups and
|
||||
work items in the grid. */
|
||||
typedef void (*gccbrigKernelLauncherFunc) (void *context, void *);
|
||||
|
||||
/* Pointer type for kernel functions produced by gccbrig from the HSAIL.
|
||||
This is private from outside the device binary and only called by
|
||||
the launcher. */
|
||||
typedef void (*gccbrigKernelFunc) (unsigned char *, void *, void *, void *);
|
||||
|
||||
/* Context data that is passed to the kernel function, initialized
|
||||
by the runtime to the current launch information. The data is
|
||||
used by different id functions etc.
|
||||
|
||||
The struct is used by both the launcher and the targeted device,
|
||||
thus the fields must have the same alignment/padding in both sides.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
|
||||
/* Data set by the HSA Runtime's kernel launcher. */
|
||||
hsa_kernel_dispatch_packet_t *dp;
|
||||
|
||||
size_t packet_id;
|
||||
|
||||
/* Data set by the device-side launcher. */
|
||||
gccbrigKernelFunc kernel;
|
||||
|
||||
/* The range of a work groups this dispatch should execute. */
|
||||
size_t wg_min_x;
|
||||
size_t wg_min_y;
|
||||
size_t wg_min_z;
|
||||
|
||||
size_t wg_max_x;
|
||||
size_t wg_max_y;
|
||||
size_t wg_max_z;
|
||||
|
||||
/* The barrier used to synch the work-items before executing a new WG. */
|
||||
void *wg_start_barrier;
|
||||
|
||||
/* The barrier to wait at after executing a work-group. */
|
||||
void *wg_completion_barrier;
|
||||
|
||||
/* The barrier used to synchronize WIs in case of the 'barrier' HSAIL
|
||||
instruction. */
|
||||
void *wg_sync_barrier;
|
||||
|
||||
/* This should be set to the flat address of the beginning of the group
|
||||
segment. */
|
||||
size_t group_segment_start_addr;
|
||||
|
||||
/* This must be set to the correct aligned flat address space location from
|
||||
where the kernel can actually read its arguments. Might point to the
|
||||
original global kernarg space. */
|
||||
void *kernarg_addr;
|
||||
} PHSAKernelLaunchData;
|
||||
|
||||
#endif
|
107
libhsail-rt/include/internal/workitems.h
Normal file
107
libhsail-rt/include/internal/workitems.h
Normal file
|
@ -0,0 +1,107 @@
|
|||
/* workitems.h -- Types for context data passed as hidden parameters to special
|
||||
built-ins.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef PHSA_RT_WORKITEMS_H
|
||||
#define PHSA_RT_WORKITEMS_H
|
||||
|
||||
/* As the simple fibers implementation relies only on ucontext, we can
|
||||
assume is found by default as it is part of glibc. However, for partial
|
||||
HSAIL support on platforms without having it available, the following define
|
||||
can be undefined. */
|
||||
#define HAVE_FIBERS
|
||||
|
||||
#ifdef HAVE_FIBERS
|
||||
#include "fibers.h"
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "phsa-rt.h"
|
||||
|
||||
/* Data identifying a single work-group instance. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* The group id of the currently executed WG. */
|
||||
size_t x;
|
||||
size_t y;
|
||||
size_t z;
|
||||
|
||||
/* This is 1 in case there are more work groups to execute.
|
||||
If 0, the work-item threads should finish themselves. */
|
||||
int more_wgs;
|
||||
|
||||
/* If the local size does not evenly divide the grid size, will have
|
||||
leftover WIs in the last execution. */
|
||||
int leftover_wg;
|
||||
int last_wg;
|
||||
|
||||
/* (Flat) pointer to the beginning of the group segment allocated
|
||||
to the work-group. */
|
||||
void *group_base_ptr;
|
||||
|
||||
/* Similarly to the private segment that gets space allocated for all
|
||||
WIs in the work-group. */
|
||||
void *private_base_ptr;
|
||||
uint32_t private_segment_total_size;
|
||||
|
||||
/* The first flat address of the group segment allocated for
|
||||
the given work group. */
|
||||
uint64_t group_segment_base_addr;
|
||||
|
||||
/* Offset from the beginning of the private segment to the start of
|
||||
the previously allocated chunk of dynamic work-item memory (alloca)
|
||||
by any WI in the WG.
|
||||
|
||||
Initially set to private_segment_total_size to denote no dynamic
|
||||
allocations have been made. The dynamic allocations are done downwards
|
||||
from the private segment end. */
|
||||
uint32_t alloca_stack_p;
|
||||
/* The position of the first word in the current function's alloca
|
||||
stack frame. Initialized to point outside the private segment. */
|
||||
uint32_t alloca_frame_p;
|
||||
|
||||
} PHSAWorkGroup;
|
||||
|
||||
/* Data identifying a single work-item, passed to the work-item thread in case
|
||||
of a fiber based work-group execution. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PHSAKernelLaunchData *launch_data;
|
||||
/* Identifies and keeps book of the currently executed WG of the WI swarm. */
|
||||
volatile PHSAWorkGroup *wg;
|
||||
/* The local id of the current WI. */
|
||||
size_t x;
|
||||
size_t y;
|
||||
size_t z;
|
||||
#ifdef HAVE_FIBERS
|
||||
fiber_t fiber;
|
||||
#endif
|
||||
} PHSAWorkItem;
|
||||
|
||||
|
||||
#endif
|
475
libhsail-rt/rt/arithmetic.c
Normal file
475
libhsail-rt/rt/arithmetic.c
Normal file
|
@ -0,0 +1,475 @@
|
|||
/* arithmetic.c -- Builtins for HSAIL arithmetic instructions for which
|
||||
there is no feasible direct gcc GENERIC expression.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
/* HSAIL defines INT_MIN % -1 to be 0 while with C it's undefined,
|
||||
and causes an overflow exception at least with gcc and C on IA-32. */
|
||||
|
||||
int32_t
|
||||
__hsail_rem_s32 (int32_t dividend, int32_t divisor)
|
||||
{
|
||||
if (dividend == INT_MIN && divisor == -1)
|
||||
return 0;
|
||||
else
|
||||
return dividend % divisor;
|
||||
}
|
||||
|
||||
int64_t
|
||||
__hsail_rem_s64 (int64_t dividend, int64_t divisor)
|
||||
{
|
||||
if (dividend == INT64_MIN && divisor == -1)
|
||||
return 0;
|
||||
else
|
||||
return dividend % divisor;
|
||||
}
|
||||
|
||||
/* HSAIL has defined behavior for min and max when one of the operands is
|
||||
NaN: in that case the other operand is returned. In C and with gcc's
|
||||
MIN_EXPR/MAX_EXPR, the returned operand is undefined. */
|
||||
|
||||
float
|
||||
__hsail_min_f32 (float a, float b)
|
||||
{
|
||||
if (isnan (a))
|
||||
return b;
|
||||
else if (isnan (b))
|
||||
return a;
|
||||
else if (a == 0.0f && b == 0.0f)
|
||||
return signbit (a) ? a : b;
|
||||
else if (a > b)
|
||||
return b;
|
||||
else
|
||||
return a;
|
||||
}
|
||||
|
||||
double
|
||||
__hsail_min_f64 (double a, double b)
|
||||
{
|
||||
if (isnan (a))
|
||||
return b;
|
||||
else if (isnan (b))
|
||||
return a;
|
||||
else if (a > b)
|
||||
return b;
|
||||
else
|
||||
return a;
|
||||
}
|
||||
|
||||
float
|
||||
__hsail_max_f32 (float a, float b)
|
||||
{
|
||||
if (isnan (a))
|
||||
return b;
|
||||
else if (isnan (b))
|
||||
return a;
|
||||
else if (a == 0.0f && b == 0.0f && signbit (a))
|
||||
return b;
|
||||
else if (a < b)
|
||||
return b;
|
||||
else
|
||||
return a;
|
||||
}
|
||||
|
||||
double
|
||||
__hsail_max_f64 (double a, double b)
|
||||
{
|
||||
if (isnan (a))
|
||||
return b;
|
||||
else if (isnan (b))
|
||||
return a;
|
||||
else if (a == 0.0 && b == 0.0 && signbit (a))
|
||||
return b;
|
||||
else if (a < b)
|
||||
return b;
|
||||
else
|
||||
return a;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
__hsail_cvt_zeroi_sat_u8_f32 (float a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (float) UINT8_MAX)
|
||||
return UINT8_MAX;
|
||||
else if (a <= 0.0f)
|
||||
return 0;
|
||||
return (uint8_t) a;
|
||||
}
|
||||
|
||||
int8_t
|
||||
__hsail_cvt_zeroi_sat_s8_f32 (float a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (float) INT8_MAX)
|
||||
return INT8_MAX;
|
||||
if (a <= (float) INT8_MIN)
|
||||
return INT8_MIN;
|
||||
return (int8_t) a;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
__hsail_cvt_zeroi_sat_u16_f32 (float a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (float) UINT16_MAX)
|
||||
return UINT16_MAX;
|
||||
else if (a <= 0.0f)
|
||||
return 0;
|
||||
return (uint16_t) a;
|
||||
}
|
||||
|
||||
int16_t
|
||||
__hsail_cvt_zeroi_sat_s16_f32 (float a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (float) INT16_MAX)
|
||||
return INT16_MAX;
|
||||
if (a <= (float) INT16_MIN)
|
||||
return INT16_MIN;
|
||||
return (int16_t) a;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_cvt_zeroi_sat_u32_f32 (float a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (float) UINT32_MAX)
|
||||
return UINT32_MAX;
|
||||
else if (a <= 0.0f)
|
||||
return 0;
|
||||
return (uint32_t) a;
|
||||
}
|
||||
|
||||
int32_t
|
||||
__hsail_cvt_zeroi_sat_s32_f32 (float a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (float) INT32_MAX)
|
||||
return INT32_MAX;
|
||||
if (a <= (float) INT32_MIN)
|
||||
return INT32_MIN;
|
||||
return (int32_t) a;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_cvt_zeroi_sat_u64_f32 (float a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (float) UINT64_MAX)
|
||||
return UINT64_MAX;
|
||||
else if (a <= 0.0f)
|
||||
return 0;
|
||||
return (uint64_t) a;
|
||||
}
|
||||
|
||||
int64_t
|
||||
__hsail_cvt_zeroi_sat_s64_f32 (float a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (float) INT64_MAX)
|
||||
return INT64_MAX;
|
||||
if (a <= (float) INT64_MIN)
|
||||
return INT64_MIN;
|
||||
return (int64_t) a;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
__hsail_cvt_zeroi_sat_u8_f64 (double a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (double) UINT8_MAX)
|
||||
return UINT8_MAX;
|
||||
else if (a <= 0.0f)
|
||||
return 0;
|
||||
return (uint8_t) a;
|
||||
}
|
||||
|
||||
int8_t
|
||||
__hsail_cvt_zeroi_sat_s8_f64 (double a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (double) INT8_MAX)
|
||||
return INT8_MAX;
|
||||
if (a <= (double) INT8_MIN)
|
||||
return INT8_MIN;
|
||||
return (int8_t) a;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
__hsail_cvt_zeroi_sat_u16_f64 (double a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (double) UINT16_MAX)
|
||||
return UINT16_MAX;
|
||||
else if (a <= 0.0f)
|
||||
return 0;
|
||||
return (uint16_t) a;
|
||||
}
|
||||
|
||||
int16_t
|
||||
__hsail_cvt_zeroi_sat_s16_f64 (double a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (double) INT16_MAX)
|
||||
return INT16_MAX;
|
||||
if (a <= (double) INT16_MIN)
|
||||
return INT16_MIN;
|
||||
return (int16_t) a;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_cvt_zeroi_sat_u32_f64 (double a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (double) UINT32_MAX)
|
||||
return UINT32_MAX;
|
||||
else if (a <= 0.0f)
|
||||
return 0;
|
||||
return (uint32_t) a;
|
||||
}
|
||||
|
||||
int32_t
|
||||
__hsail_cvt_zeroi_sat_s32_f64 (double a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (double) INT32_MAX)
|
||||
return INT32_MAX;
|
||||
if (a <= (double) INT32_MIN)
|
||||
return INT32_MIN;
|
||||
return (int32_t) a;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_cvt_zeroi_sat_u64_f64 (double a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (double) UINT64_MAX)
|
||||
return UINT64_MAX;
|
||||
else if (a <= 0.0f)
|
||||
return 0;
|
||||
return (uint64_t) a;
|
||||
}
|
||||
|
||||
int64_t
|
||||
__hsail_cvt_zeroi_sat_s64_f64 (double a)
|
||||
{
|
||||
if (isnan (a))
|
||||
return 0;
|
||||
if (a >= (double) INT64_MAX)
|
||||
return INT64_MAX;
|
||||
if (a <= (double) INT64_MIN)
|
||||
return INT64_MIN;
|
||||
return (int64_t) a;
|
||||
}
|
||||
|
||||
|
||||
/* Flush the operand to zero in case it's a denormalized number.
|
||||
Do not cause any exceptions in case of NaNs. */
|
||||
|
||||
float
|
||||
__hsail_ftz_f32 (float a)
|
||||
{
|
||||
if (isnan (a) || isinf (a) || a == 0.0f)
|
||||
return a;
|
||||
|
||||
if (a < 0.0f)
|
||||
{
|
||||
if (-a < FLT_MIN)
|
||||
return -0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a < FLT_MIN)
|
||||
return 0.0f;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
#define F16_MIN (6.10e-5)
|
||||
|
||||
/* Flush the single precision operand to zero in case it's considered
|
||||
a denormalized number in case it was a f16. Do not cause any exceptions
|
||||
in case of NaNs. */
|
||||
|
||||
float
|
||||
__hsail_ftz_f32_f16 (float a)
|
||||
{
|
||||
if (isnan (a) || isinf (a) || a == 0.0f)
|
||||
return a;
|
||||
|
||||
if (a < 0.0f)
|
||||
{
|
||||
if (-a < F16_MIN)
|
||||
return -0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a < F16_MIN)
|
||||
return 0.0f;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
double
|
||||
__hsail_ftz_f64 (double a)
|
||||
{
|
||||
if (isnan (a) || isinf (a) || a == 0.0d)
|
||||
return a;
|
||||
|
||||
if (a < 0.0d)
|
||||
{
|
||||
if (-a < DBL_MIN)
|
||||
return -0.0d;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (a < DBL_MIN)
|
||||
return 0.0d;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_borrow_u32 (uint32_t a, uint32_t b)
|
||||
{
|
||||
uint64_t c = (uint64_t) a - (uint64_t) b;
|
||||
if (c > UINT32_MAX)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_borrow_u64 (uint64_t a, uint64_t b)
|
||||
{
|
||||
__uint128_t c = (__uint128_t) a - (__uint128_t) b;
|
||||
if (c > UINT64_MAX)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_carry_u32 (uint32_t a, uint32_t b)
|
||||
{
|
||||
uint64_t c = (uint64_t) a + (uint64_t) b;
|
||||
if (c > UINT32_MAX)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_carry_u64 (uint64_t a, uint64_t b)
|
||||
{
|
||||
__uint128_t c = (__uint128_t) a + (__uint128_t) b;
|
||||
if (c > UINT64_MAX)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
float
|
||||
__hsail_fract_f32 (float a)
|
||||
{
|
||||
int exp;
|
||||
if (isinf (a))
|
||||
return signbit (a) == 0 ? 0.0f : -0.0f;
|
||||
if (isnan (a) || a == 0.0f)
|
||||
return a;
|
||||
else
|
||||
return fminf (a - floorf (a), 0x1.fffffep-1f);
|
||||
}
|
||||
|
||||
double
|
||||
__hsail_fract_f64 (double a)
|
||||
{
|
||||
int exp;
|
||||
if (isinf (a))
|
||||
return 0.0f * isinf (a);
|
||||
if (isnan (a) || a == 0.0f)
|
||||
return a;
|
||||
else
|
||||
return fmin (a - floor (a), 0x1.fffffffffffffp-1d);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_class_f32 (float a, uint32_t flags)
|
||||
{
|
||||
return (flags & 0x0001 && isnan (a) && !(*(uint32_t *) &a & 0x40000000))
|
||||
|| (flags & 0x0002 && isnan (a) && (*(uint32_t *) &a & 0x40000000))
|
||||
|| (flags & 0x0004 && isinf (a) && a < 0.0f)
|
||||
|| (flags & 0x0008 && isnormal (a) && signbit (a))
|
||||
|| (flags & 0x0010 && a < 0.0f && a > -FLT_MIN)
|
||||
|| (flags & 0x0020 && a == 0.0f && signbit (a))
|
||||
|| (flags & 0x0040 && a == 0.0f && !signbit (a))
|
||||
|| (flags & 0x0080 && a > 0.0f && a < FLT_MIN)
|
||||
|| (flags & 0x0100 && isnormal (a) && !signbit (a))
|
||||
|| (flags & 0x0200 && isinf (a) && a >= 0.0f);
|
||||
}
|
||||
|
||||
/* 'class' for a f32-converted f16 which should otherwise be treated like f32
|
||||
except for its limits. */
|
||||
|
||||
uint32_t
|
||||
__hsail_class_f32_f16 (float a, uint32_t flags)
|
||||
{
|
||||
return (flags & 0x0001 && isnan (a) && !(*(uint32_t *) &a & 0x40000000))
|
||||
|| (flags & 0x0002 && isnan (a) && (*(uint32_t *) &a & 0x40000000))
|
||||
|| (flags & 0x0004 && isinf (a) && a < 0.0f)
|
||||
|| (flags & 0x0008 && a != 0.0f && !isinf (a) && !isnan (a)
|
||||
&& a <= -F16_MIN)
|
||||
|| (flags & 0x0010 && a != 0.0f && !isinf (a) && !isnan (a) && a < 0.0f
|
||||
&& a > -F16_MIN)
|
||||
|| (flags & 0x0020 && a == 0.0f && signbit (a))
|
||||
|| (flags & 0x0040 && a == 0.0f && !signbit (a))
|
||||
|| (flags & 0x0080 && a != 0.0f && !isinf (a) && !isnan (a) && a > 0.0f
|
||||
&& a < F16_MIN)
|
||||
|| (flags & 0x0100 && a != 0.0f && !isinf (a) && !isnan (a)
|
||||
&& a >= F16_MIN)
|
||||
|| (flags & 0x0200 && isinf (a) && a >= 0.0f);
|
||||
}
|
115
libhsail-rt/rt/atomics.c
Normal file
115
libhsail-rt/rt/atomics.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/* atomic.c -- Builtins for HSAIL atomic instructions for which
|
||||
there is no feasible direct gcc GENERIC expression.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define DO_ATOMICALLY(T, OPERATION) \
|
||||
int done = 0; \
|
||||
T old_value; \
|
||||
T new_value; \
|
||||
while (!done) \
|
||||
{ \
|
||||
old_value = *ptr; \
|
||||
new_value = OPERATION; \
|
||||
done = __sync_bool_compare_and_swap (ptr, old_value, new_value); \
|
||||
} \
|
||||
return old_value
|
||||
|
||||
int32_t
|
||||
__hsail_atomic_min_s32 (int32_t *ptr, int32_t a)
|
||||
{
|
||||
DO_ATOMICALLY (int32_t, (old_value < a) ? old_value : a);
|
||||
}
|
||||
|
||||
int64_t
|
||||
__hsail_atomic_min_s64 (int64_t *ptr, int64_t a)
|
||||
{
|
||||
DO_ATOMICALLY (int64_t, (old_value < a) ? old_value : a);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_atomic_min_u32 (uint32_t *ptr, uint32_t a)
|
||||
{
|
||||
DO_ATOMICALLY (uint32_t, (old_value < a) ? old_value : a);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_atomic_min_u64 (uint64_t *ptr, uint64_t a)
|
||||
{
|
||||
DO_ATOMICALLY (uint64_t, (old_value < a) ? old_value : a);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_atomic_max_u32 (uint32_t *ptr, uint32_t a)
|
||||
{
|
||||
DO_ATOMICALLY (uint32_t, (old_value > a) ? old_value : a);
|
||||
}
|
||||
|
||||
int32_t
|
||||
__hsail_atomic_max_s32 (int32_t *ptr, int32_t a)
|
||||
{
|
||||
DO_ATOMICALLY (int32_t, (old_value > a) ? old_value : a);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_atomic_max_u64 (uint64_t *ptr, uint64_t a)
|
||||
{
|
||||
DO_ATOMICALLY (uint64_t, (old_value > a) ? old_value : a);
|
||||
}
|
||||
|
||||
int64_t
|
||||
__hsail_atomic_max_s64 (int64_t *ptr, int64_t a)
|
||||
{
|
||||
DO_ATOMICALLY (int64_t, (old_value > a) ? old_value : a);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_atomic_wrapinc_u32 (uint32_t *ptr, uint32_t a)
|
||||
{
|
||||
DO_ATOMICALLY (uint32_t, (old_value >= a) ? 0 : (old_value + 1));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_atomic_wrapinc_u64 (uint64_t *ptr, uint64_t a)
|
||||
{
|
||||
DO_ATOMICALLY (uint64_t, (old_value >= a) ? 0 : (old_value + 1));
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_atomic_wrapdec_u32 (uint32_t *ptr, uint32_t a)
|
||||
{
|
||||
DO_ATOMICALLY (uint32_t,
|
||||
((old_value == 0) || (old_value > a)) ? a : (old_value - 1));
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_atomic_wrapdec_u64 (uint64_t *ptr, uint64_t a)
|
||||
{
|
||||
DO_ATOMICALLY (uint64_t,
|
||||
((old_value == 0) || (old_value > a)) ? a : (old_value - 1));
|
||||
}
|
190
libhsail-rt/rt/bitstring.c
Normal file
190
libhsail-rt/rt/bitstring.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/* bitstring.c -- Builtins for HSAIL bitstring instructions.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define BITEXTRACT(DEST_TYPE, SRC0, SRC1, SRC2) \
|
||||
uint32_t offset = SRC1 & (sizeof (DEST_TYPE) * 8 - 1); \
|
||||
uint32_t width = SRC2 & (sizeof (DEST_TYPE) * 8 - 1); \
|
||||
if (width == 0) \
|
||||
return 0; \
|
||||
else \
|
||||
return (SRC0 << (sizeof (DEST_TYPE) * 8 - width - offset)) \
|
||||
>> (sizeof (DEST_TYPE) * 8 - width)
|
||||
|
||||
uint32_t
|
||||
__hsail_bitextract_u32 (uint32_t src0, uint32_t src1, uint32_t src2)
|
||||
{
|
||||
BITEXTRACT (uint32_t, src0, src1, src2);
|
||||
}
|
||||
|
||||
int32_t
|
||||
__hsail_bitextract_s32 (int32_t src0, uint32_t src1, uint32_t src2)
|
||||
{
|
||||
BITEXTRACT (int32_t, src0, src1, src2);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_bitextract_u64 (uint64_t src0, uint32_t src1, uint32_t src2)
|
||||
{
|
||||
BITEXTRACT (uint64_t, src0, src1, src2);
|
||||
}
|
||||
|
||||
int64_t
|
||||
__hsail_bitextract_s64 (int64_t src0, uint32_t src1, uint32_t src2)
|
||||
{
|
||||
BITEXTRACT (int64_t, src0, src1, src2);
|
||||
}
|
||||
|
||||
#define BITINSERT(DEST_TYPE, SRC0, SRC1, SRC2, SRC3) \
|
||||
uint32_t offset = SRC2 & (sizeof (DEST_TYPE) * 8 - 1); \
|
||||
uint32_t width = SRC3 & (sizeof (DEST_TYPE) * 8 - 1); \
|
||||
DEST_TYPE mask = ((DEST_TYPE) 1 << width) - 1; \
|
||||
return (SRC0 & ~(mask << offset)) | ((SRC1 & mask) << offset)
|
||||
|
||||
uint32_t
|
||||
__hsail_bitinsert_u32 (uint32_t src0, uint32_t src1, uint32_t src2,
|
||||
uint32_t src3)
|
||||
{
|
||||
BITINSERT (uint32_t, src0, src1, src2, src3);
|
||||
}
|
||||
|
||||
int64_t
|
||||
__hsail_bitinsert_u64 (uint64_t src0, uint64_t src1, uint32_t src2,
|
||||
uint32_t src3)
|
||||
{
|
||||
BITINSERT (uint64_t, src0, src1, src2, src3);
|
||||
}
|
||||
|
||||
#define BITMASK(DEST_TYPE, SRC0, SRC1) \
|
||||
uint32_t offset = SRC0 & (sizeof (DEST_TYPE) * 8 - 1); \
|
||||
uint32_t width = SRC1 & (sizeof (DEST_TYPE) * 8 - 1); \
|
||||
DEST_TYPE mask = ((DEST_TYPE) 1 << width) - 1; \
|
||||
return mask << offset
|
||||
|
||||
uint32_t
|
||||
__hsail_bitmask_u32 (uint32_t src0, uint32_t src1)
|
||||
{
|
||||
BITMASK (uint32_t, src0, src1);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_bitmask_u64 (uint32_t src0, uint32_t src1)
|
||||
{
|
||||
BITMASK (uint64_t, src0, src1);
|
||||
}
|
||||
|
||||
/* The dummy, but readable version from
|
||||
http://graphics.stanford.edu/~seander/bithacks.html#BitReverseObvious
|
||||
This (also) often maps to a single instruction in DSPs. */
|
||||
|
||||
#define BITREV(DEST_TYPE, SRC) \
|
||||
DEST_TYPE v = SRC; \
|
||||
DEST_TYPE r = v; \
|
||||
int s = sizeof (SRC) * CHAR_BIT - 1; \
|
||||
\
|
||||
for (v >>= 1; v; v >>= 1) \
|
||||
{ \
|
||||
r <<= 1; \
|
||||
r |= v & 1; \
|
||||
s--; \
|
||||
} \
|
||||
return r << s
|
||||
|
||||
uint32_t
|
||||
__hsail_bitrev_u32 (uint32_t src0)
|
||||
{
|
||||
BITREV (uint32_t, src0);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_bitrev_u64 (uint64_t src0)
|
||||
{
|
||||
BITREV (uint64_t, src0);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_bitselect_u32 (uint32_t src0, uint32_t src1, uint32_t src2)
|
||||
{
|
||||
return (src1 & src0) | (src2 & ~src0);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_bitselect_u64 (uint64_t src0, uint64_t src1, uint64_t src2)
|
||||
{
|
||||
return (src1 & src0) | (src2 & ~src0);
|
||||
}
|
||||
|
||||
/* Due to the defined behavior with 0, we cannot use the gcc builtin
|
||||
__builtin_clz* () directly. __builtin_ffs () has defined behavior, but
|
||||
returns 0 while HSAIL requires to return -1. */
|
||||
|
||||
uint32_t
|
||||
__hsail_firstbit_u32 (uint32_t src0)
|
||||
{
|
||||
if (src0 == 0)
|
||||
return -1;
|
||||
return __builtin_clz (src0);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_firstbit_s32 (int32_t src0)
|
||||
{
|
||||
uint32_t converted = src0 >= 0 ? src0 : ~src0;
|
||||
return __hsail_firstbit_u32 (converted);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_firstbit_u64 (uint64_t src0)
|
||||
{
|
||||
if (src0 == 0)
|
||||
return -1;
|
||||
return __builtin_clzl (src0);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_firstbit_s64 (int64_t src0)
|
||||
{
|
||||
uint64_t converted = src0 >= 0 ? src0 : ~src0;
|
||||
return __hsail_firstbit_u64 (converted);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_lastbit_u32 (uint32_t src0)
|
||||
{
|
||||
if (src0 == 0)
|
||||
return -1;
|
||||
return __builtin_ctz (src0);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_lastbit_u64 (uint64_t src0)
|
||||
{
|
||||
if (src0 == 0)
|
||||
return -1;
|
||||
return __builtin_ctzl (src0);
|
||||
}
|
87
libhsail-rt/rt/fbarrier.c
Normal file
87
libhsail-rt/rt/fbarrier.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/* fbarrier.c -- HSAIL fbarrier built-ins.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "workitems.h"
|
||||
#include "phsa-rt.h"
|
||||
|
||||
#ifdef HAVE_FIBERS
|
||||
#include "fibers.h"
|
||||
|
||||
typedef fiber_barrier_t fbarrier;
|
||||
|
||||
void
|
||||
__hsail_initfbar (uint32_t addr, PHSAWorkItem *wi)
|
||||
{
|
||||
fbarrier *fbar = (fbarrier *) (wi->wg->group_base_ptr + addr);
|
||||
fbar->threshold = 0;
|
||||
fbar->reached = 0;
|
||||
fbar->waiting_count = 0;
|
||||
}
|
||||
|
||||
void
|
||||
__hsail_releasefbar (uint32_t addr, PHSAWorkItem *wi)
|
||||
{
|
||||
fbarrier *fbar = (fbarrier *) (wi->wg->group_base_ptr + addr);
|
||||
fbar->threshold = 0;
|
||||
fbar->reached = 0;
|
||||
fbar->waiting_count = 0;
|
||||
}
|
||||
|
||||
void
|
||||
__hsail_joinfbar (uint32_t addr, PHSAWorkItem *wi)
|
||||
{
|
||||
fbarrier *fbar = (fbarrier *) (wi->wg->group_base_ptr + addr);
|
||||
++fbar->threshold;
|
||||
}
|
||||
|
||||
void
|
||||
__hsail_leavefbar (uint32_t addr, PHSAWorkItem *wi)
|
||||
{
|
||||
fbarrier *fbar = (fbarrier *) (wi->wg->group_base_ptr + addr);
|
||||
--fbar->threshold;
|
||||
}
|
||||
|
||||
void
|
||||
__hsail_waitfbar (uint32_t addr, PHSAWorkItem *wi)
|
||||
{
|
||||
fbarrier *fbar = (fbarrier *) (wi->wg->group_base_ptr + addr);
|
||||
fiber_barrier_reach (fbar);
|
||||
}
|
||||
|
||||
void
|
||||
__hsail_arrivefbar (uint32_t addr, PHSAWorkItem *wi)
|
||||
{
|
||||
fbarrier *fbar = (fbarrier *) (wi->wg->group_base_ptr + addr);
|
||||
++fbar->reached;
|
||||
if (fbar->reached == fbar->threshold)
|
||||
fbar->reached = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
220
libhsail-rt/rt/fibers.c
Normal file
220
libhsail-rt/rt/fibers.c
Normal file
|
@ -0,0 +1,220 @@
|
|||
/* fibers.c -- extremely simple lightweight thread (fiber) implementation
|
||||
Copyright (C) 2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "target-config.h"
|
||||
|
||||
#include "fibers.h"
|
||||
|
||||
void
|
||||
phsa_fatal_error (int code);
|
||||
|
||||
ucontext_t main_context;
|
||||
|
||||
/* The last fiber in the linked list. */
|
||||
static fiber_t *tail_fiber = NULL;
|
||||
/* The first fiber in the linked list. */
|
||||
static fiber_t *head_fiber = NULL;
|
||||
/* The fiber currently being executed. */
|
||||
static fiber_t *current_fiber = NULL;
|
||||
|
||||
/* Makecontext accepts only integer arguments. We need to split the
|
||||
pointer argument in case pointer does not fit into int. This helper
|
||||
function can be used to restore the pointer from the arguments. */
|
||||
|
||||
void *
|
||||
fiber_int_args_to_ptr (int arg0, int arg1)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
#if SIZEOF_VOIDP == 8 && SIZEOF_INT == 4
|
||||
ptr = (void*)(((uint64_t) arg0 & (uint64_t) 0xFFFFFFFF)
|
||||
| ((uint64_t) arg1 << 32));
|
||||
#elif SIZEOF_VOIDP == 4 && SIZEOF_INT == 4
|
||||
ptr = (void*)arg0;
|
||||
#else
|
||||
# error Unsupported pointer/int size.
|
||||
#endif
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void
|
||||
fiber_init (fiber_t *fiber, fiber_function_t start_function, void *arg,
|
||||
size_t stack_size, size_t stack_align)
|
||||
{
|
||||
int arg0, arg1;
|
||||
if (getcontext (&fiber->context) != 0)
|
||||
phsa_fatal_error (3);
|
||||
if (posix_memalign (&fiber->context.uc_stack.ss_sp, stack_align, stack_size)
|
||||
!= 0)
|
||||
phsa_fatal_error (4);
|
||||
fiber->context.uc_stack.ss_size = stack_size;
|
||||
fiber->context.uc_link = &main_context;
|
||||
|
||||
/* makecontext () accepts only integer arguments. Split the
|
||||
pointer argument to two args in the case pointer does not fit
|
||||
into one int. */
|
||||
#if SIZEOF_VOIDP == 8 && SIZEOF_INT == 4
|
||||
arg0 = (int32_t) 0xFFFFFFFF & (uint64_t)arg;
|
||||
arg1 = (int32_t) 0xFFFFFFFF & ((uint64_t)arg >> 32);
|
||||
#elif SIZEOF_VOIDP == 4 && SIZEOF_INT == 4
|
||||
arg0 = (int)arg;
|
||||
arg1 = 0;
|
||||
#else
|
||||
# error Unsupported pointer/int size.
|
||||
#endif
|
||||
|
||||
makecontext (&fiber->context, (void*)start_function, 2, arg0, arg1);
|
||||
|
||||
fiber->status = FIBER_STATUS_READY;
|
||||
fiber->next = NULL;
|
||||
fiber->prev = NULL;
|
||||
|
||||
/* Create a linked list of the created fibers. Append the new one at
|
||||
the end. */
|
||||
if (tail_fiber == NULL)
|
||||
tail_fiber = fiber;
|
||||
else
|
||||
{
|
||||
tail_fiber->next = fiber;
|
||||
fiber->prev = tail_fiber;
|
||||
tail_fiber = fiber;
|
||||
}
|
||||
|
||||
if (head_fiber == NULL)
|
||||
head_fiber = fiber;
|
||||
}
|
||||
|
||||
void
|
||||
fiber_exit ()
|
||||
{
|
||||
fiber_status_t old_status = current_fiber->status;
|
||||
current_fiber->status = FIBER_STATUS_EXITED;
|
||||
if (old_status == FIBER_STATUS_JOINED)
|
||||
/* In case this thread has been joined, return back to the joiner. */
|
||||
swapcontext (¤t_fiber->context, &main_context);
|
||||
else
|
||||
/* In case the thread exited while being yielded from another thread,
|
||||
switch back to another fiber. */
|
||||
fiber_yield ();
|
||||
}
|
||||
|
||||
void
|
||||
fiber_join (fiber_t *fiber)
|
||||
{
|
||||
fiber_t *next_ready_fiber = NULL;
|
||||
current_fiber = fiber;
|
||||
if (fiber->status != FIBER_STATUS_EXITED)
|
||||
{
|
||||
fiber->status = FIBER_STATUS_JOINED;
|
||||
while (fiber->status != FIBER_STATUS_EXITED)
|
||||
swapcontext (&main_context, &fiber->context);
|
||||
}
|
||||
|
||||
/* Remove the successfully joined fiber from the linked list so we won't
|
||||
access it later (the fiber itself might be freed after the join). */
|
||||
if (fiber->prev != NULL)
|
||||
fiber->prev->next = fiber->next;
|
||||
|
||||
if (fiber->next != NULL)
|
||||
fiber->next->prev = fiber->prev;
|
||||
|
||||
if (head_fiber == fiber)
|
||||
head_fiber = fiber->next;
|
||||
|
||||
if (tail_fiber == fiber)
|
||||
tail_fiber = fiber->prev;
|
||||
|
||||
free (fiber->context.uc_stack.ss_sp);
|
||||
}
|
||||
|
||||
void
|
||||
fiber_yield ()
|
||||
{
|
||||
fiber_t *next_ready_fiber = current_fiber;
|
||||
|
||||
if (current_fiber == head_fiber
|
||||
&& current_fiber == tail_fiber)
|
||||
{
|
||||
/* If the last fiber exits independently, there is no
|
||||
fiber to switch to. Switch to the main context in that
|
||||
case. */
|
||||
if (current_fiber->status == FIBER_STATUS_EXITED)
|
||||
swapcontext (¤t_fiber->context, &main_context);
|
||||
}
|
||||
|
||||
do {
|
||||
next_ready_fiber = next_ready_fiber->next != NULL
|
||||
? next_ready_fiber->next : head_fiber;
|
||||
} while (next_ready_fiber != current_fiber
|
||||
&& next_ready_fiber->status == FIBER_STATUS_EXITED);
|
||||
|
||||
fiber_t *old_current_fiber = current_fiber;
|
||||
current_fiber = next_ready_fiber;
|
||||
swapcontext (&old_current_fiber->context, &next_ready_fiber->context);
|
||||
}
|
||||
|
||||
size_t
|
||||
fiber_barrier_reach (fiber_barrier_t *barrier)
|
||||
{
|
||||
/* Yield once to ensure that there are no fibers waiting for
|
||||
a previous triggering of the barrier in the waiting_count
|
||||
loop. This should release them before we update the reached
|
||||
counter again. */
|
||||
fiber_yield ();
|
||||
|
||||
barrier->reached++;
|
||||
++barrier->waiting_count;
|
||||
while (barrier->reached < barrier->threshold)
|
||||
fiber_yield ();
|
||||
--barrier->waiting_count;
|
||||
|
||||
/* Wait until all the fibers have reached this point. */
|
||||
while (barrier->waiting_count > 0)
|
||||
fiber_yield ();
|
||||
|
||||
/* Now all fibers have been released from the barrier waiting
|
||||
loop. We can now safely reset the reach count for new triggering. */
|
||||
if (barrier->reached > 0)
|
||||
{
|
||||
barrier->reached = 0;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
fiber_barrier_init (fiber_barrier_t *barrier, size_t threshold)
|
||||
{
|
||||
barrier->threshold = threshold;
|
||||
barrier->waiting_count = 0;
|
||||
barrier->reached = 0;
|
||||
}
|
135
libhsail-rt/rt/fp16.c
Normal file
135
libhsail-rt/rt/fp16.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
/* Half-float conversion routines. Code mostly borrowed from the ARM's
|
||||
builtin function.
|
||||
|
||||
Copyright (C) 2008-2015 Free Software Foundation, Inc.
|
||||
Contributed by CodeSourcery.
|
||||
|
||||
This file 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.
|
||||
|
||||
This file 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/>. */
|
||||
|
||||
static inline unsigned short
|
||||
__gnu_f2h_internal (unsigned int a, int ieee)
|
||||
{
|
||||
unsigned short sign = (a >> 16) & 0x8000;
|
||||
int aexp = (a >> 23) & 0xff;
|
||||
unsigned int mantissa = a & 0x007fffff;
|
||||
unsigned int mask;
|
||||
unsigned int increment;
|
||||
|
||||
if (aexp == 0xff)
|
||||
{
|
||||
if (!ieee)
|
||||
return sign;
|
||||
if (mantissa == 0)
|
||||
return sign | 0x7c00; /* Infinity. */
|
||||
/* Remaining cases are NaNs. Convert SNaN to QNaN. */
|
||||
return sign | 0x7e00 | (mantissa >> 13);
|
||||
}
|
||||
|
||||
if (aexp == 0 && mantissa == 0)
|
||||
return sign;
|
||||
|
||||
aexp -= 127;
|
||||
|
||||
/* Decimal point between bits 22 and 23. */
|
||||
mantissa |= 0x00800000;
|
||||
if (aexp < -14)
|
||||
{
|
||||
mask = 0x00ffffff;
|
||||
if (aexp >= -25)
|
||||
mask >>= 25 + aexp;
|
||||
}
|
||||
else
|
||||
mask = 0x00001fff;
|
||||
|
||||
/* Round. */
|
||||
if (mantissa & mask)
|
||||
{
|
||||
increment = (mask + 1) >> 1;
|
||||
if ((mantissa & mask) == increment)
|
||||
increment = mantissa & (increment << 1);
|
||||
mantissa += increment;
|
||||
if (mantissa >= 0x01000000)
|
||||
{
|
||||
mantissa >>= 1;
|
||||
aexp++;
|
||||
}
|
||||
}
|
||||
|
||||
if (ieee)
|
||||
{
|
||||
if (aexp > 15)
|
||||
return sign | 0x7c00;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (aexp > 16)
|
||||
return sign | 0x7fff;
|
||||
}
|
||||
|
||||
if (aexp < -24)
|
||||
return sign;
|
||||
|
||||
if (aexp < -14)
|
||||
{
|
||||
mantissa >>= -14 - aexp;
|
||||
aexp = -14;
|
||||
}
|
||||
|
||||
/* We leave the leading 1 in the mantissa, and subtract one
|
||||
from the exponent bias to compensate. */
|
||||
return sign | (((aexp + 14) << 10) + (mantissa >> 13));
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
__gnu_h2f_internal (unsigned short a, int ieee)
|
||||
{
|
||||
unsigned int sign = (unsigned int) (a & 0x8000) << 16;
|
||||
int aexp = (a >> 10) & 0x1f;
|
||||
unsigned int mantissa = a & 0x3ff;
|
||||
|
||||
if (aexp == 0x1f && ieee)
|
||||
return sign | 0x7f800000 | (mantissa << 13);
|
||||
|
||||
if (aexp == 0)
|
||||
{
|
||||
int shift;
|
||||
|
||||
if (mantissa == 0)
|
||||
return sign;
|
||||
|
||||
shift = __builtin_clz (mantissa) - 21;
|
||||
mantissa <<= shift;
|
||||
aexp = -shift;
|
||||
}
|
||||
|
||||
return sign | (((aexp + 0x70) << 23) + (mantissa << 13));
|
||||
}
|
||||
|
||||
unsigned short
|
||||
__hsail_f32_to_f16 (unsigned int a)
|
||||
{
|
||||
return __gnu_f2h_internal (a, 1);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
__hsail_f16_to_f32 (unsigned short a)
|
||||
{
|
||||
return __gnu_h2f_internal (a, 1);
|
||||
}
|
89
libhsail-rt/rt/misc.c
Normal file
89
libhsail-rt/rt/misc.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
/* misc.c -- Builtins for HSAIL misc instructions.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "workitems.h"
|
||||
|
||||
/* Return the monotonic clock as nanoseconds. */
|
||||
|
||||
uint64_t
|
||||
__hsail_clock ()
|
||||
{
|
||||
struct timespec t;
|
||||
clock_gettime (CLOCK_MONOTONIC, &t);
|
||||
return (uint64_t) t.tv_sec * 1000000000 + (uint64_t) t.tv_nsec;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_cuid (PHSAWorkItem *wi)
|
||||
{
|
||||
/* All WIs are executed with a single compute unit (core/thread)
|
||||
for now. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_maxcuid (PHSAWorkItem *wi)
|
||||
{
|
||||
/* All WIs are executed with a single compute unit (core/thread)
|
||||
for now. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
__hsail_debugtrap (uint32_t src, PHSAWorkItem *wi)
|
||||
{
|
||||
/* Could we produce a SIGTRAP signal here to drop to gdb
|
||||
console, or similar? In any case, the execution of the
|
||||
kernel should halt.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_groupbaseptr (PHSAWorkItem *wi)
|
||||
{
|
||||
return (uint32_t) (uint64_t) (wi->wg->group_base_ptr
|
||||
- wi->launch_data->group_segment_start_addr);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_kernargbaseptr_u64 (PHSAWorkItem *wi)
|
||||
{
|
||||
/* For now assume only a single kernarg allocation at a time.
|
||||
Proper kernarg memory management to do. */
|
||||
return (uint64_t) wi->launch_data->kernarg_addr;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_kernargbaseptr_u32 (PHSAWorkItem *wi)
|
||||
{
|
||||
/* For now assume only a single kernarg allocation at a time.
|
||||
Proper kernarg memory management to do. */
|
||||
return 0;
|
||||
}
|
135
libhsail-rt/rt/multimedia.c
Normal file
135
libhsail-rt/rt/multimedia.c
Normal file
|
@ -0,0 +1,135 @@
|
|||
/* multimedia.c -- Builtins for HSAIL multimedia instructions.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
uint32_t
|
||||
__hsail_bitalign (uint64_t lower, uint64_t upper, uint32_t shift_amount)
|
||||
{
|
||||
shift_amount = shift_amount & 31;
|
||||
uint64_t packed_value = (upper << 32) | lower;
|
||||
return (packed_value >> shift_amount) & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_bytealign (uint64_t lower, uint64_t upper, uint32_t shift_amount)
|
||||
{
|
||||
shift_amount = (shift_amount & 3) * 8;
|
||||
uint64_t packed_value = (upper << 32) | lower;
|
||||
return (packed_value >> shift_amount) & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_lerp (uint32_t a, uint32_t b, uint32_t c)
|
||||
{
|
||||
uint32_t e3
|
||||
= (((((a >> 24) & 0xff) + ((b >> 24) & 0xff) + ((c >> 24) & 0x1)) / 2)
|
||||
& 0xff)
|
||||
<< 24;
|
||||
uint32_t e2
|
||||
= (((((a >> 16) & 0xff) + ((b >> 16) & 0xff) + ((c >> 16) & 0x1)) / 2)
|
||||
& 0xff)
|
||||
<< 16;
|
||||
uint32_t e1
|
||||
= (((((a >> 8) & 0xff) + ((b >> 8) & 0xff) + ((c >> 8) & 0x1)) / 2) & 0xff)
|
||||
<< 8;
|
||||
uint32_t e0 = (((a & 0xff) + (b & 0xff) + (c & 0x1)) / 2) & 0xff;
|
||||
|
||||
return e3 | e2 | e1 | e0;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
cvt_neari_sat_u8_f32 (float a)
|
||||
{
|
||||
if (isinf (a))
|
||||
{
|
||||
if (signbit (a)) return 0;
|
||||
else return 255;
|
||||
}
|
||||
else if (isnan (a)) return 0;
|
||||
else if (a < 0.0)
|
||||
return 0;
|
||||
else if (a > 255.0)
|
||||
return 255;
|
||||
else
|
||||
return (uint8_t) a;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_packcvt (float a, float b, float c, float d)
|
||||
{
|
||||
return (uint32_t) cvt_neari_sat_u8_f32 (a)
|
||||
| (uint32_t) cvt_neari_sat_u8_f32 (b) << 8
|
||||
| (uint32_t) cvt_neari_sat_u8_f32 (c) << 16
|
||||
| (uint32_t) cvt_neari_sat_u8_f32 (d) << 24;
|
||||
}
|
||||
|
||||
float
|
||||
__hsail_unpackcvt (uint32_t val, uint32_t index)
|
||||
{
|
||||
return (float) ((val >> (index * 8)) & 0xff);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
abs_diff (uint32_t a, uint32_t b)
|
||||
{
|
||||
if (a < b)
|
||||
return b - a;
|
||||
else
|
||||
return a - b;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_sad_u8x4 (uint32_t a, uint32_t b, uint32_t add)
|
||||
{
|
||||
return abs_diff ((a >> 24) & 0xff, (b >> 24) & 0xff)
|
||||
+ abs_diff ((a >> 16) & 0xff, (b >> 16) & 0xff)
|
||||
+ abs_diff ((a >> 8) & 0xff, (b >> 8) & 0xff)
|
||||
+ abs_diff ((a >> 0) & 0xff, (b >> 0) & 0xff) + add;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_sad_u16x2 (uint32_t a, uint32_t b, uint32_t add)
|
||||
{
|
||||
return abs_diff ((a >> 16) & 0xffff, (b >> 16) & 0xffff)
|
||||
+ abs_diff ((a >> 0) & 0xffff, (b >> 0) & 0xffff) + add;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_sad_u32 (uint32_t a, uint32_t b, uint32_t add)
|
||||
{
|
||||
return abs_diff (a, b) + add;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_sadhi_u16x2_u8x4 (uint32_t a, uint32_t b, uint32_t add)
|
||||
{
|
||||
return (abs_diff ((a >> 24) & 0xff, (b >> 24) & 0xff) << 16)
|
||||
+ (abs_diff ((a >> 16) & 0xff, (b >> 16) & 0xff) << 16)
|
||||
+ (abs_diff ((a >> 8) & 0xff, (b >> 8) & 0xff) << 16)
|
||||
+ (abs_diff ((a >> 0) & 0xff, (b >> 0) & 0xff) << 16) + add;
|
||||
}
|
71
libhsail-rt/rt/queue.c
Normal file
71
libhsail-rt/rt/queue.c
Normal file
|
@ -0,0 +1,71 @@
|
|||
/* queue.c -- Builtins for HSAIL queue related instructions.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "phsa-queue-interface.h"
|
||||
|
||||
uint64_t
|
||||
__hsail_ldqueuereadindex (uint64_t queue_addr)
|
||||
{
|
||||
phsa_queue_t *queue = (phsa_queue_t *) queue_addr;
|
||||
return queue->read_index;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_ldqueuewriteindex (uint64_t queue_addr)
|
||||
{
|
||||
phsa_queue_t *queue = (phsa_queue_t *) queue_addr;
|
||||
return queue->write_index;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_addqueuewriteindex (uint64_t queue_addr, uint64_t value)
|
||||
{
|
||||
phsa_queue_t *queue = (phsa_queue_t *) queue_addr;
|
||||
return __sync_fetch_and_add (&queue->write_index, value);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_casqueuewriteindex (uint64_t queue_addr, uint64_t cmp_value,
|
||||
uint64_t new_value)
|
||||
{
|
||||
phsa_queue_t *queue = (phsa_queue_t *) queue_addr;
|
||||
return __sync_val_compare_and_swap (&queue->write_index, cmp_value,
|
||||
new_value);
|
||||
}
|
||||
|
||||
void
|
||||
__hsail_stqueuereadindex (uint64_t queue_addr, uint64_t value)
|
||||
{
|
||||
phsa_queue_t *queue = (phsa_queue_t *) queue_addr;
|
||||
queue->read_index = value;
|
||||
}
|
||||
|
||||
void
|
||||
__hsail_stqueuewriteindex (uint64_t queue_addr, uint64_t value)
|
||||
{
|
||||
phsa_queue_t *queue = (phsa_queue_t *) queue_addr;
|
||||
queue->write_index = value;
|
||||
}
|
299
libhsail-rt/rt/sat_arithmetic.c
Normal file
299
libhsail-rt/rt/sat_arithmetic.c
Normal file
|
@ -0,0 +1,299 @@
|
|||
/* sat_arithmetic.c -- Builtins for HSAIL saturating arithmetic instructions.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t
|
||||
__hsail_sat_add_u8 (uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t c = (uint16_t) a + (uint16_t) b;
|
||||
if (c > UINT8_MAX)
|
||||
return UINT8_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
__hsail_sat_add_u16 (uint16_t a, uint16_t b)
|
||||
{
|
||||
uint32_t c = (uint32_t) a + (uint32_t) b;
|
||||
if (c > UINT16_MAX)
|
||||
return UINT16_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_sat_add_u32 (uint32_t a, uint32_t b)
|
||||
{
|
||||
uint64_t c = (uint64_t) a + (uint64_t) b;
|
||||
if (c > UINT32_MAX)
|
||||
return UINT32_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_sat_add_u64 (uint64_t a, uint64_t b)
|
||||
{
|
||||
__uint128_t c = (__uint128_t) a + (__uint128_t) b;
|
||||
if (c > UINT64_MAX)
|
||||
return UINT64_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int8_t
|
||||
__hsail_sat_add_s8 (int8_t a, int8_t b)
|
||||
{
|
||||
int16_t c = (int16_t) a + (int16_t) b;
|
||||
if (c > INT8_MAX)
|
||||
return INT8_MAX;
|
||||
else if (c < INT8_MIN)
|
||||
return INT8_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int16_t
|
||||
__hsail_sat_add_s16 (int16_t a, int16_t b)
|
||||
{
|
||||
int32_t c = (int32_t) a + (int32_t) b;
|
||||
if (c > INT16_MAX)
|
||||
return INT16_MAX;
|
||||
else if (c < INT16_MIN)
|
||||
return INT16_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int32_t
|
||||
__hsail_sat_add_s32 (int32_t a, int32_t b)
|
||||
{
|
||||
int64_t c = (int64_t) a + (int64_t) b;
|
||||
if (c > INT32_MAX)
|
||||
return INT32_MAX;
|
||||
else if (c < INT32_MIN)
|
||||
return INT32_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int64_t
|
||||
__hsail_sat_add_s64 (int64_t a, int64_t b)
|
||||
{
|
||||
__int128_t c = (__int128_t) a + (__int128_t) b;
|
||||
if (c > INT64_MAX)
|
||||
return INT64_MAX;
|
||||
else if (c < INT64_MIN)
|
||||
return INT64_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
__hsail_sat_sub_u8 (uint8_t a, uint8_t b)
|
||||
{
|
||||
int16_t c = (uint16_t) a - (uint16_t) b;
|
||||
if (c < 0)
|
||||
return 0;
|
||||
else if (c > UINT8_MAX)
|
||||
return UINT8_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
__hsail_sat_sub_u16 (uint16_t a, uint16_t b)
|
||||
{
|
||||
int32_t c = (uint32_t) a - (uint32_t) b;
|
||||
if (c < 0)
|
||||
return 0;
|
||||
else if (c > UINT16_MAX)
|
||||
return UINT16_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_sat_sub_u32 (uint32_t a, uint32_t b)
|
||||
{
|
||||
int64_t c = (uint64_t) a - (uint64_t) b;
|
||||
if (c < 0)
|
||||
return 0;
|
||||
else if (c > UINT32_MAX)
|
||||
return UINT32_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_sat_sub_u64 (uint64_t a, uint64_t b)
|
||||
{
|
||||
__int128_t c = (__uint128_t) a - (__uint128_t) b;
|
||||
if (c < 0)
|
||||
return 0;
|
||||
else if (c > UINT64_MAX)
|
||||
return UINT64_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int8_t
|
||||
__hsail_sat_sub_s8 (int8_t a, int8_t b)
|
||||
{
|
||||
int16_t c = (int16_t) a - (int16_t) b;
|
||||
if (c > INT8_MAX)
|
||||
return INT8_MAX;
|
||||
else if (c < INT8_MIN)
|
||||
return INT8_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int16_t
|
||||
__hsail_sat_sub_s16 (int16_t a, int16_t b)
|
||||
{
|
||||
int32_t c = (int32_t) a - (int32_t) b;
|
||||
if (c > INT16_MAX)
|
||||
return INT16_MAX;
|
||||
else if (c < INT16_MIN)
|
||||
return INT16_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int32_t
|
||||
__hsail_sat_sub_s32 (int32_t a, int32_t b)
|
||||
{
|
||||
int64_t c = (int64_t) a - (int64_t) b;
|
||||
if (c > INT32_MAX)
|
||||
return INT32_MAX;
|
||||
else if (c < INT32_MIN)
|
||||
return INT32_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int64_t
|
||||
__hsail_sat_sub_s64 (int64_t a, int64_t b)
|
||||
{
|
||||
__int128_t c = (__int128_t) a - (__int128_t) b;
|
||||
if (c > INT64_MAX)
|
||||
return INT64_MAX;
|
||||
else if (c < INT64_MIN)
|
||||
return INT64_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
__hsail_sat_mul_u8 (uint8_t a, uint8_t b)
|
||||
{
|
||||
uint16_t c = (uint16_t) a * (uint16_t) b;
|
||||
if (c > UINT8_MAX)
|
||||
return UINT8_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
__hsail_sat_mul_u16 (uint16_t a, uint16_t b)
|
||||
{
|
||||
uint32_t c = (uint32_t) a * (uint32_t) b;
|
||||
if (c > UINT16_MAX)
|
||||
return UINT16_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_sat_mul_u32 (uint32_t a, uint32_t b)
|
||||
{
|
||||
uint64_t c = (uint64_t) a * (uint64_t) b;
|
||||
if (c > UINT32_MAX)
|
||||
return UINT32_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_sat_mul_u64 (uint64_t a, uint64_t b)
|
||||
{
|
||||
__uint128_t c = (__uint128_t) a * (__uint128_t) b;
|
||||
if (c > UINT64_MAX)
|
||||
return UINT64_MAX;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int8_t
|
||||
__hsail_sat_mul_s8 (int8_t a, int8_t b)
|
||||
{
|
||||
int16_t c = (int16_t) a * (int16_t) b;
|
||||
if (c > INT8_MAX)
|
||||
return INT8_MAX;
|
||||
else if (c < INT8_MIN)
|
||||
return INT8_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int16_t
|
||||
__hsail_sat_mul_s16 (int16_t a, int16_t b)
|
||||
{
|
||||
int32_t c = (int32_t) a * (int32_t) b;
|
||||
if (c > INT16_MAX)
|
||||
return INT16_MAX;
|
||||
else if (c < INT16_MIN)
|
||||
return INT16_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int32_t
|
||||
__hsail_sat_mul_s32 (int32_t a, int32_t b)
|
||||
{
|
||||
int64_t c = (int64_t) a * (int64_t) b;
|
||||
if (c > INT32_MAX)
|
||||
return INT32_MAX;
|
||||
else if (c < INT32_MIN)
|
||||
return INT32_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
int64_t
|
||||
__hsail_sat_mul_s64 (int64_t a, int64_t b)
|
||||
{
|
||||
__int128_t c = (__int128_t) a * (__int128_t) b;
|
||||
if (c > INT64_MAX)
|
||||
return INT64_MAX;
|
||||
else if (c < INT64_MIN)
|
||||
return INT64_MIN;
|
||||
else
|
||||
return c;
|
||||
}
|
57
libhsail-rt/rt/segment.c
Normal file
57
libhsail-rt/rt/segment.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
/* segment.c -- Builtins for HSAIL segment related instructions.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "workitems.h"
|
||||
|
||||
uint32_t
|
||||
__hsail_segmentp_private (uint64_t flat_addr, PHSAWorkItem *wi)
|
||||
{
|
||||
if (flat_addr == 0)
|
||||
return 1;
|
||||
else
|
||||
return (void *) flat_addr >= wi->wg->private_base_ptr
|
||||
&& (void *) flat_addr
|
||||
< wi->wg->private_base_ptr + wi->wg->private_segment_total_size;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_segmentp_group (uint64_t flat_addr, PHSAWorkItem *wi)
|
||||
{
|
||||
if (flat_addr == 0)
|
||||
return 1;
|
||||
else
|
||||
return (void *) flat_addr >= wi->wg->group_base_ptr
|
||||
&& (void *) flat_addr < wi->wg->group_base_ptr
|
||||
+ wi->launch_data->dp->group_segment_size;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_segmentp_global (uint64_t flat_addr, PHSAWorkItem *wi)
|
||||
{
|
||||
return (flat_addr == 0
|
||||
|| (!__hsail_segmentp_private (flat_addr, wi)
|
||||
&& !__hsail_segmentp_group (flat_addr, wi)));
|
||||
}
|
952
libhsail-rt/rt/workitems.c
Normal file
952
libhsail-rt/rt/workitems.c
Normal file
|
@ -0,0 +1,952 @@
|
|||
/* workitems.c -- The main runtime entry that performs work-item execution in
|
||||
various ways and the builtin functions closely related to the
|
||||
implementation.
|
||||
|
||||
Copyright (C) 2015-2016 Free Software Foundation, Inc.
|
||||
Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
|
||||
for General Processor Tech.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files
|
||||
(the "Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* The fiber based multiple work-item work-group execution uses ucontext
|
||||
based user mode threading. However, if gccbrig is able to optimize the
|
||||
kernel to a much faster work-group function that implements the multiple
|
||||
WI execution using loops instead of fibers requiring slow context switches,
|
||||
the fiber-based implementation won't be called.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "workitems.h"
|
||||
#include "phsa-rt.h"
|
||||
|
||||
#ifdef HAVE_FIBERS
|
||||
#include "fibers.h"
|
||||
#endif
|
||||
|
||||
#ifdef BENCHMARK_PHSA_RT
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
static uint64_t wi_count = 0;
|
||||
static uint64_t wis_skipped = 0;
|
||||
static uint64_t wi_total = 0;
|
||||
static clock_t start_time;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_PHSA_RT
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#define PRIVATE_SEGMENT_ALIGN 256
|
||||
#define FIBER_STACK_SIZE (64*1024)
|
||||
#define GROUP_SEGMENT_ALIGN 256
|
||||
|
||||
/* HSA requires WGs to be executed in flat work-group id order. Enabling
|
||||
the following macro can reveal test cases that rely on the ordering,
|
||||
but is not useful for much else. */
|
||||
|
||||
uint32_t __hsail_workitemabsid (uint32_t dim, PHSAWorkItem *context);
|
||||
|
||||
uint32_t __hsail_workitemid (uint32_t dim, PHSAWorkItem *context);
|
||||
|
||||
uint32_t __hsail_gridgroups (uint32_t dim, PHSAWorkItem *context);
|
||||
|
||||
uint32_t __hsail_currentworkgroupsize (uint32_t dim, PHSAWorkItem *wi);
|
||||
|
||||
uint32_t __hsail_workgroupsize (uint32_t dim, PHSAWorkItem *wi);
|
||||
|
||||
void
|
||||
phsa_fatal_error (int code)
|
||||
{
|
||||
exit (code);
|
||||
}
|
||||
|
||||
#ifdef HAVE_FIBERS
|
||||
/* ucontext-based work-item thread implementation. Runs all work-items in
|
||||
separate fibers. */
|
||||
|
||||
static void
|
||||
phsa_work_item_thread (int arg0, int arg1)
|
||||
{
|
||||
void *arg = fiber_int_args_to_ptr (arg0, arg1);
|
||||
|
||||
PHSAWorkItem *wi = (PHSAWorkItem *) arg;
|
||||
volatile PHSAWorkGroup *wg = wi->wg;
|
||||
PHSAKernelLaunchData *l_data = wi->launch_data;
|
||||
|
||||
do
|
||||
{
|
||||
int retcode
|
||||
= fiber_barrier_reach ((fiber_barrier_t *) l_data->wg_start_barrier);
|
||||
|
||||
/* At this point the threads can assume that either more_wgs is 0 or
|
||||
the current_work_group_* is set to point to the WG executed next. */
|
||||
if (!wi->wg->more_wgs)
|
||||
break;
|
||||
#ifdef DEBUG_PHSA_RT
|
||||
printf (
|
||||
"Running work-item %lu/%lu/%lu for wg %lu/%lu/%lu / %lu/%lu/%lu...\n",
|
||||
wi->x, wi->y, wi->z, wg->x, wg->y, wg->z, l_data->wg_max_x,
|
||||
l_data->wg_max_y, l_data->wg_max_z);
|
||||
#endif
|
||||
|
||||
if (wi->x < __hsail_currentworkgroupsize (0, wi)
|
||||
&& wi->y < __hsail_currentworkgroupsize (1, wi)
|
||||
&& wi->z < __hsail_currentworkgroupsize (2, wi))
|
||||
{
|
||||
l_data->kernel (l_data->kernarg_addr, wi, wg->group_base_ptr,
|
||||
wg->private_base_ptr);
|
||||
#ifdef DEBUG_PHSA_RT
|
||||
printf ("done.\n");
|
||||
#endif
|
||||
#ifdef BENCHMARK_PHSA_RT
|
||||
wi_count++;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_PHSA_RT
|
||||
printf ("skipped (partial WG).\n");
|
||||
#endif
|
||||
#ifdef BENCHMARK_PHSA_RT
|
||||
wis_skipped++;
|
||||
#endif
|
||||
}
|
||||
|
||||
retcode
|
||||
= fiber_barrier_reach ((fiber_barrier_t *)
|
||||
l_data->wg_completion_barrier);
|
||||
|
||||
/* The first thread updates the WG to execute next etc. */
|
||||
|
||||
if (retcode == 0)
|
||||
{
|
||||
#ifdef EXECUTE_WGS_BACKWARDS
|
||||
if (wg->x == l_data->wg_min_x)
|
||||
{
|
||||
wg->x = l_data->wg_max_x - 1;
|
||||
if (wg->y == l_data->wg_min_y)
|
||||
{
|
||||
wg->y = l_data->wg_max_y - 1;
|
||||
if (wg->z == l_data->wg_min_z)
|
||||
wg->more_wgs = 0;
|
||||
else
|
||||
wg->z--;
|
||||
}
|
||||
else
|
||||
wg->y--;
|
||||
}
|
||||
else
|
||||
wg->x--;
|
||||
#else
|
||||
if (wg->x + 1 >= l_data->wg_max_x)
|
||||
{
|
||||
wg->x = l_data->wg_min_x;
|
||||
if (wg->y + 1 >= l_data->wg_max_y)
|
||||
{
|
||||
wg->y = l_data->wg_min_y;
|
||||
if (wg->z + 1 >= l_data->wg_max_z)
|
||||
wg->more_wgs = 0;
|
||||
else
|
||||
wg->z++;
|
||||
}
|
||||
else
|
||||
wg->y++;
|
||||
}
|
||||
else
|
||||
wg->x++;
|
||||
#endif
|
||||
|
||||
/* Reinitialize the work-group barrier according to the new WG's
|
||||
size, which might not be the same as the previous ones, due
|
||||
to "partial WGs". */
|
||||
size_t wg_size = __hsail_currentworkgroupsize (0, wi)
|
||||
* __hsail_currentworkgroupsize (1, wi)
|
||||
* __hsail_currentworkgroupsize (2, wi);
|
||||
|
||||
#ifdef DEBUG_PHSA_RT
|
||||
printf ("Reinitializing the WG barrier to %lu.\n", wg_size);
|
||||
#endif
|
||||
fiber_barrier_init ((fiber_barrier_t *)
|
||||
wi->launch_data->wg_sync_barrier,
|
||||
wg_size);
|
||||
|
||||
#ifdef BENCHMARK_PHSA_RT
|
||||
if (wi_count % 1000 == 0)
|
||||
{
|
||||
clock_t spent_time = clock () - start_time;
|
||||
double spent_time_sec = (double) spent_time / CLOCKS_PER_SEC;
|
||||
double wis_per_sec = wi_count / spent_time_sec;
|
||||
uint64_t eta_sec
|
||||
= (wi_total - wi_count - wis_skipped) / wis_per_sec;
|
||||
|
||||
printf ("%lu WIs executed %lu skipped in %lus (%lu WIs/s, ETA in "
|
||||
"%lu s)\n",
|
||||
wi_count, wis_skipped, (uint64_t) spent_time_sec,
|
||||
(uint64_t) wis_per_sec, (uint64_t) eta_sec);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
|
||||
fiber_exit ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MIN(a, b) ((a < b) ? a : b)
|
||||
#define MAX(a, b) ((a > b) ? a : b)
|
||||
|
||||
#ifdef HAVE_FIBERS
|
||||
/* Spawns a given number of work-items to execute a set of work-groups,
|
||||
blocks until their completion. */
|
||||
|
||||
static void
|
||||
phsa_execute_wi_gang (PHSAKernelLaunchData *context, void *group_base_ptr,
|
||||
size_t wg_size_x, size_t wg_size_y, size_t wg_size_z)
|
||||
{
|
||||
PHSAWorkItem *wi_threads = NULL;
|
||||
PHSAWorkGroup wg;
|
||||
size_t flat_wi_id = 0, x, y, z, max_x, max_y, max_z;
|
||||
fiber_barrier_t wg_start_barrier;
|
||||
fiber_barrier_t wg_completion_barrier;
|
||||
fiber_barrier_t wg_sync_barrier;
|
||||
|
||||
max_x = wg_size_x == 0 ? 1 : wg_size_x;
|
||||
max_y = wg_size_y == 0 ? 1 : wg_size_y;
|
||||
max_z = wg_size_z == 0 ? 1 : wg_size_z;
|
||||
|
||||
size_t wg_size = max_x * max_y * max_z;
|
||||
if (wg_size > PHSA_MAX_WG_SIZE)
|
||||
phsa_fatal_error (2);
|
||||
|
||||
wg.private_segment_total_size = context->dp->private_segment_size * wg_size;
|
||||
if (wg.private_segment_total_size > 0
|
||||
&& posix_memalign (&wg.private_base_ptr, PRIVATE_SEGMENT_ALIGN,
|
||||
wg.private_segment_total_size)
|
||||
!= 0)
|
||||
phsa_fatal_error (3);
|
||||
|
||||
wg.alloca_stack_p = wg.private_segment_total_size;
|
||||
wg.alloca_frame_p = wg.alloca_stack_p;
|
||||
|
||||
#ifdef EXECUTE_WGS_BACKWARDS
|
||||
wg.x = context->wg_max_x - 1;
|
||||
wg.y = context->wg_max_y - 1;
|
||||
wg.z = context->wg_max_z - 1;
|
||||
#else
|
||||
wg.x = context->wg_min_x;
|
||||
wg.y = context->wg_min_y;
|
||||
wg.z = context->wg_min_z;
|
||||
#endif
|
||||
|
||||
fiber_barrier_init (&wg_sync_barrier, wg_size);
|
||||
fiber_barrier_init (&wg_start_barrier, wg_size);
|
||||
fiber_barrier_init (&wg_completion_barrier, wg_size);
|
||||
|
||||
context->wg_start_barrier = &wg_start_barrier;
|
||||
context->wg_sync_barrier = &wg_sync_barrier;
|
||||
context->wg_completion_barrier = &wg_completion_barrier;
|
||||
|
||||
wg.more_wgs = 1;
|
||||
wg.group_base_ptr = group_base_ptr;
|
||||
|
||||
#ifdef BENCHMARK_PHSA_RT
|
||||
wi_count = 0;
|
||||
wis_skipped = 0;
|
||||
start_time = clock ();
|
||||
#endif
|
||||
wi_threads = malloc (sizeof (PHSAWorkItem) * max_x * max_y * max_z);
|
||||
for (x = 0; x < max_x; ++x)
|
||||
for (y = 0; y < max_y; ++y)
|
||||
for (z = 0; z < max_z; ++z)
|
||||
{
|
||||
PHSAWorkItem *wi = &wi_threads[flat_wi_id];
|
||||
wi->launch_data = context;
|
||||
wi->wg = &wg;
|
||||
wi->x = x;
|
||||
wi->y = y;
|
||||
wi->z = z;
|
||||
|
||||
/* TODO: set the stack size according to the private
|
||||
segment size. Too big stack consumes huge amount of
|
||||
memory in case of huge number of WIs and a too small stack
|
||||
will fail in mysterious and potentially dangerous ways. */
|
||||
|
||||
fiber_init (&wi->fiber, phsa_work_item_thread, wi,
|
||||
FIBER_STACK_SIZE, PRIVATE_SEGMENT_ALIGN);
|
||||
++flat_wi_id;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
--flat_wi_id;
|
||||
fiber_join (&wi_threads[flat_wi_id].fiber);
|
||||
}
|
||||
while (flat_wi_id > 0);
|
||||
|
||||
if (wg.private_segment_total_size > 0)
|
||||
free (wg.private_base_ptr);
|
||||
|
||||
free (wi_threads);
|
||||
}
|
||||
|
||||
/* Spawn the work-item threads to execute work-groups and let
|
||||
them execute all the WGs, including a potential partial WG. */
|
||||
|
||||
static void
|
||||
phsa_spawn_work_items (PHSAKernelLaunchData *context, void *group_base_ptr)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = context->dp;
|
||||
size_t x, y, z;
|
||||
|
||||
/* TO DO: host-side memory management of group and private segment
|
||||
memory. Agents in general are less likely to support efficient dynamic mem
|
||||
allocation. */
|
||||
if (dp->group_segment_size > 0
|
||||
&& posix_memalign (&group_base_ptr, PRIVATE_SEGMENT_ALIGN,
|
||||
dp->group_segment_size) != 0)
|
||||
phsa_fatal_error (3);
|
||||
|
||||
context->group_segment_start_addr = (size_t) group_base_ptr;
|
||||
|
||||
/* HSA seems to allow the WG size to be larger than the grid size. We need to
|
||||
saturate the effective WG size to the grid size to prevent the extra WIs
|
||||
from executing. */
|
||||
size_t sat_wg_size_x, sat_wg_size_y, sat_wg_size_z, sat_wg_size;
|
||||
sat_wg_size_x = MIN (dp->workgroup_size_x, dp->grid_size_x);
|
||||
sat_wg_size_y = MIN (dp->workgroup_size_y, dp->grid_size_y);
|
||||
sat_wg_size_z = MIN (dp->workgroup_size_z, dp->grid_size_z);
|
||||
sat_wg_size = sat_wg_size_x * sat_wg_size_y * sat_wg_size_z;
|
||||
|
||||
#ifdef BENCHMARK_PHSA_RT
|
||||
wi_total = (uint64_t) dp->grid_size_x
|
||||
* (dp->grid_size_y > 0 ? dp->grid_size_y : 1)
|
||||
* (dp->grid_size_z > 0 ? dp->grid_size_z : 1);
|
||||
#endif
|
||||
|
||||
/* For now execute all work groups in a single coarse thread (does not utilize
|
||||
multicore/multithread). */
|
||||
context->wg_min_x = context->wg_min_y = context->wg_min_z = 0;
|
||||
|
||||
int dims = dp->setup & 0x3;
|
||||
|
||||
context->wg_max_x = ((uint64_t) dp->grid_size_x + dp->workgroup_size_x - 1)
|
||||
/ dp->workgroup_size_x;
|
||||
|
||||
context->wg_max_y
|
||||
= dims < 2 ? 1 : ((uint64_t) dp->grid_size_y + dp->workgroup_size_y - 1)
|
||||
/ dp->workgroup_size_y;
|
||||
|
||||
context->wg_max_z
|
||||
= dims < 3 ? 1 : ((uint64_t) dp->grid_size_z + dp->workgroup_size_z - 1)
|
||||
/ dp->workgroup_size_z;
|
||||
|
||||
#ifdef DEBUG_PHSA_RT
|
||||
printf ("### launching work-groups %lu/%lu/%lu to %lu/%lu/%lu with "
|
||||
"wg size %lu/%lu/%lu grid size %u/%u/%u\n",
|
||||
context->wg_min_x, context->wg_min_y, context->wg_min_z,
|
||||
context->wg_max_x, context->wg_max_y, context->wg_max_z,
|
||||
sat_wg_size_x, sat_wg_size_y, sat_wg_size_z, dp->grid_size_x,
|
||||
dp->grid_size_y, dp->grid_size_z);
|
||||
#endif
|
||||
|
||||
phsa_execute_wi_gang (context, group_base_ptr, sat_wg_size_x, sat_wg_size_y,
|
||||
sat_wg_size_z);
|
||||
|
||||
if (dp->group_segment_size > 0)
|
||||
free (group_base_ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Executes the given work-group function for all work groups in the grid.
|
||||
|
||||
A work-group function is a version of the original kernel which executes
|
||||
the kernel for all work-items in a work-group. It is produced by gccbrig
|
||||
if it can handle the kernel's barrier usage and is much faster way to
|
||||
execute massive numbers of work-items in a non-SPMD machine than fibers
|
||||
(easily 100x faster). */
|
||||
static void
|
||||
phsa_execute_work_groups (PHSAKernelLaunchData *context, void *group_base_ptr)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = context->dp;
|
||||
size_t x, y, z, wg_x, wg_y, wg_z;
|
||||
|
||||
/* TODO: host-side memory management of group and private segment
|
||||
memory. Agents in general are less likely to support efficient dynamic mem
|
||||
allocation. */
|
||||
if (dp->group_segment_size > 0
|
||||
&& posix_memalign (&group_base_ptr, GROUP_SEGMENT_ALIGN,
|
||||
dp->group_segment_size) != 0)
|
||||
phsa_fatal_error (3);
|
||||
|
||||
context->group_segment_start_addr = (size_t) group_base_ptr;
|
||||
|
||||
/* HSA seems to allow the WG size to be larger than the grid size. We need
|
||||
to saturate the effective WG size to the grid size to prevent the extra WIs
|
||||
from executing. */
|
||||
size_t sat_wg_size_x, sat_wg_size_y, sat_wg_size_z, sat_wg_size;
|
||||
sat_wg_size_x = MIN (dp->workgroup_size_x, dp->grid_size_x);
|
||||
sat_wg_size_y = MIN (dp->workgroup_size_y, dp->grid_size_y);
|
||||
sat_wg_size_z = MIN (dp->workgroup_size_z, dp->grid_size_z);
|
||||
sat_wg_size = sat_wg_size_x * sat_wg_size_y * sat_wg_size_z;
|
||||
|
||||
#ifdef BENCHMARK_PHSA_RT
|
||||
wi_total = (uint64_t) dp->grid_size_x
|
||||
* (dp->grid_size_y > 0 ? dp->grid_size_y : 1)
|
||||
* (dp->grid_size_z > 0 ? dp->grid_size_z : 1);
|
||||
#endif
|
||||
|
||||
context->wg_min_x = context->wg_min_y = context->wg_min_z = 0;
|
||||
|
||||
int dims = dp->setup & 0x3;
|
||||
|
||||
context->wg_max_x = ((uint64_t) dp->grid_size_x + dp->workgroup_size_x - 1)
|
||||
/ dp->workgroup_size_x;
|
||||
|
||||
context->wg_max_y
|
||||
= dims < 2 ? 1 : ((uint64_t) dp->grid_size_y + dp->workgroup_size_y - 1)
|
||||
/ dp->workgroup_size_y;
|
||||
|
||||
context->wg_max_z
|
||||
= dims < 3 ? 1 : ((uint64_t) dp->grid_size_z + dp->workgroup_size_z - 1)
|
||||
/ dp->workgroup_size_z;
|
||||
|
||||
#ifdef DEBUG_PHSA_RT
|
||||
printf ("### launching work-groups %lu/%lu/%lu to %lu/%lu/%lu with "
|
||||
"wg size %lu/%lu/%lu grid size %u/%u/%u\n",
|
||||
context->wg_min_x, context->wg_min_y, context->wg_min_z,
|
||||
context->wg_max_x, context->wg_max_y, context->wg_max_z,
|
||||
sat_wg_size_x, sat_wg_size_y, sat_wg_size_z, dp->grid_size_x,
|
||||
dp->grid_size_y, dp->grid_size_z);
|
||||
#endif
|
||||
|
||||
PHSAWorkItem wi;
|
||||
PHSAWorkGroup wg;
|
||||
wi.wg = &wg;
|
||||
wi.x = wi.y = wi.z = 0;
|
||||
wi.launch_data = context;
|
||||
|
||||
#ifdef BENCHMARK_PHSA_RT
|
||||
start_time = clock ();
|
||||
uint64_t wg_count = 0;
|
||||
#endif
|
||||
|
||||
size_t wg_size = __hsail_workgroupsize (0, &wi)
|
||||
* __hsail_workgroupsize (1, &wi)
|
||||
* __hsail_workgroupsize (2, &wi);
|
||||
|
||||
void *private_base_ptr = NULL;
|
||||
if (dp->private_segment_size > 0
|
||||
&& posix_memalign (&private_base_ptr, PRIVATE_SEGMENT_ALIGN,
|
||||
dp->private_segment_size * wg_size)
|
||||
!= 0)
|
||||
phsa_fatal_error (3);
|
||||
|
||||
wg.alloca_stack_p = dp->private_segment_size * wg_size;
|
||||
wg.alloca_frame_p = wg.alloca_stack_p;
|
||||
|
||||
wg.private_base_ptr = private_base_ptr;
|
||||
wg.group_base_ptr = group_base_ptr;
|
||||
|
||||
#ifdef DEBUG_PHSA_RT
|
||||
printf ("priv seg size %u wg_size %lu @ %p\n", dp->private_segment_size,
|
||||
wg_size, private_base_ptr);
|
||||
#endif
|
||||
|
||||
for (wg_z = context->wg_min_z; wg_z < context->wg_max_z; ++wg_z)
|
||||
for (wg_y = context->wg_min_y; wg_y < context->wg_max_y; ++wg_y)
|
||||
for (wg_x = context->wg_min_x; wg_x < context->wg_max_x; ++wg_x)
|
||||
{
|
||||
wi.wg->x = wg_x;
|
||||
wi.wg->y = wg_y;
|
||||
wi.wg->z = wg_z;
|
||||
|
||||
context->kernel (context->kernarg_addr, &wi, group_base_ptr,
|
||||
private_base_ptr);
|
||||
|
||||
#if defined (BENCHMARK_PHSA_RT)
|
||||
wg_count++;
|
||||
if (wg_count % 1000000 == 0)
|
||||
{
|
||||
clock_t spent_time = clock () - start_time;
|
||||
uint64_t wi_count = wg_x * sat_wg_size_x + wg_y * sat_wg_size_y
|
||||
+ wg_z * sat_wg_size_z;
|
||||
double spent_time_sec = (double) spent_time / CLOCKS_PER_SEC;
|
||||
double wis_per_sec = wi_count / spent_time_sec;
|
||||
uint64_t eta_sec = (wi_total - wi_count) / wis_per_sec;
|
||||
|
||||
printf ("%lu WIs executed in %lus (%lu WIs/s, ETA in %lu s)\n",
|
||||
wi_count, (uint64_t) spent_time_sec,
|
||||
(uint64_t) wis_per_sec, (uint64_t) eta_sec);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BENCHMARK_PHSA_RT
|
||||
clock_t spent_time = clock () - start_time;
|
||||
double spent_time_sec = (double) spent_time / CLOCKS_PER_SEC;
|
||||
double wis_per_sec = wi_total / spent_time_sec;
|
||||
|
||||
printf ("### %lu WIs executed in %lu s (%lu WIs / s)\n", wi_total,
|
||||
(uint64_t) spent_time_sec, (uint64_t) wis_per_sec);
|
||||
#endif
|
||||
|
||||
if (dp->group_segment_size > 0)
|
||||
free (group_base_ptr);
|
||||
|
||||
free (private_base_ptr);
|
||||
private_base_ptr = NULL;
|
||||
}
|
||||
|
||||
/* gccbrig generates the following from each HSAIL kernel:
|
||||
|
||||
1) The actual kernel function (a single work-item kernel or a work-group
|
||||
function) generated from HSAIL (BRIG).
|
||||
|
||||
static void _Kernel (void* args, void* context, void* group_base_ptr)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
2) A public facing kernel function that is called from the PHSA runtime:
|
||||
|
||||
a) A single work-item function (that requires fibers for multi-WI):
|
||||
|
||||
void Kernel (void* context)
|
||||
{
|
||||
__launch_launch_kernel (_Kernel, context);
|
||||
}
|
||||
|
||||
or
|
||||
|
||||
b) a when gccbrig could generate a work-group function:
|
||||
|
||||
void Kernel (void* context)
|
||||
{
|
||||
__hsail_launch_wg_function (_Kernel, context);
|
||||
}
|
||||
*/
|
||||
|
||||
#ifdef HAVE_FIBERS
|
||||
|
||||
void
|
||||
__hsail_launch_kernel (gccbrigKernelFunc kernel, PHSAKernelLaunchData *context,
|
||||
void *group_base_ptr)
|
||||
{
|
||||
context->kernel = kernel;
|
||||
phsa_spawn_work_items (context, group_base_ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
__hsail_launch_wg_function (gccbrigKernelFunc kernel,
|
||||
PHSAKernelLaunchData *context, void *group_base_ptr)
|
||||
{
|
||||
context->kernel = kernel;
|
||||
phsa_execute_work_groups (context, group_base_ptr);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_workitemabsid (uint32_t dim, PHSAWorkItem *context)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = context->launch_data->dp;
|
||||
|
||||
uint32_t id;
|
||||
switch (dim)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
/* Overflow semantics in the case of WG dim > grid dim. */
|
||||
id = ((uint64_t) context->wg->x * dp->workgroup_size_x + context->x)
|
||||
% dp->grid_size_x;
|
||||
break;
|
||||
case 1:
|
||||
id = ((uint64_t) context->wg->y * dp->workgroup_size_y + context->y)
|
||||
% dp->grid_size_y;
|
||||
break;
|
||||
case 2:
|
||||
id = ((uint64_t) context->wg->z * dp->workgroup_size_z + context->z)
|
||||
% dp->grid_size_z;
|
||||
break;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_workitemabsid_u64 (uint32_t dim, PHSAWorkItem *context)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = context->launch_data->dp;
|
||||
|
||||
uint64_t id;
|
||||
switch (dim)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
/* Overflow semantics in the case of WG dim > grid dim. */
|
||||
id = ((uint64_t) context->wg->x * dp->workgroup_size_x + context->x)
|
||||
% dp->grid_size_x;
|
||||
break;
|
||||
case 1:
|
||||
id = ((uint64_t) context->wg->y * dp->workgroup_size_y + context->y)
|
||||
% dp->grid_size_y;
|
||||
break;
|
||||
case 2:
|
||||
id = ((uint64_t) context->wg->z * dp->workgroup_size_z + context->z)
|
||||
% dp->grid_size_z;
|
||||
break;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
uint32_t
|
||||
__hsail_workitemid (uint32_t dim, PHSAWorkItem *context)
|
||||
{
|
||||
PHSAWorkItem *c = (PHSAWorkItem *) context;
|
||||
hsa_kernel_dispatch_packet_t *dp = context->launch_data->dp;
|
||||
|
||||
/* The number of dimensions is in the two least significant bits. */
|
||||
int dims = dp->setup & 0x3;
|
||||
|
||||
uint32_t id;
|
||||
switch (dim)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
id = c->x;
|
||||
break;
|
||||
case 1:
|
||||
id = dims < 2 ? 0 : c->y;
|
||||
break;
|
||||
case 2:
|
||||
id = dims < 3 ? 0 : c->z;
|
||||
break;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_gridgroups (uint32_t dim, PHSAWorkItem *context)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = context->launch_data->dp;
|
||||
int dims = dp->setup & 0x3;
|
||||
|
||||
uint32_t id;
|
||||
switch (dim)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
id = (dp->grid_size_x + dp->workgroup_size_x - 1) / dp->workgroup_size_x;
|
||||
break;
|
||||
case 1:
|
||||
id = dims < 2 ? 1 : (dp->grid_size_y + dp->workgroup_size_y - 1)
|
||||
/ dp->workgroup_size_y;
|
||||
break;
|
||||
case 2:
|
||||
id = dims < 3 ? 1 : (dp->grid_size_z + dp->workgroup_size_z - 1)
|
||||
/ dp->workgroup_size_z;
|
||||
break;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_workitemflatid (PHSAWorkItem *c)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = c->launch_data->dp;
|
||||
|
||||
return c->x + c->y * dp->workgroup_size_x
|
||||
+ c->z * dp->workgroup_size_x * dp->workgroup_size_y;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_currentworkitemflatid (PHSAWorkItem *c)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = c->launch_data->dp;
|
||||
|
||||
return c->x + c->y * __hsail_currentworkgroupsize (0, c)
|
||||
+ c->z * __hsail_currentworkgroupsize (0, c)
|
||||
* __hsail_currentworkgroupsize (1, c);
|
||||
}
|
||||
|
||||
void
|
||||
__hsail_setworkitemid (uint32_t dim, uint32_t id, PHSAWorkItem *context)
|
||||
{
|
||||
switch (dim)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
context->x = id;
|
||||
break;
|
||||
case 1:
|
||||
context->y = id;
|
||||
break;
|
||||
case 2:
|
||||
context->z = id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_workitemflatabsid_u64 (PHSAWorkItem *context)
|
||||
{
|
||||
PHSAWorkItem *c = (PHSAWorkItem *) context;
|
||||
hsa_kernel_dispatch_packet_t *dp = context->launch_data->dp;
|
||||
|
||||
/* Work-item flattened absolute ID = ID0 + ID1 * max0 + ID2 * max0 * max1. */
|
||||
uint64_t id0 = __hsail_workitemabsid (0, context);
|
||||
uint64_t id1 = __hsail_workitemabsid (1, context);
|
||||
uint64_t id2 = __hsail_workitemabsid (2, context);
|
||||
|
||||
uint64_t max0 = dp->grid_size_x;
|
||||
uint64_t max1 = dp->grid_size_y;
|
||||
uint64_t id = id0 + id1 * max0 + id2 * max0 * max1;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_workitemflatabsid_u32 (PHSAWorkItem *context)
|
||||
{
|
||||
PHSAWorkItem *c = (PHSAWorkItem *) context;
|
||||
hsa_kernel_dispatch_packet_t *dp = context->launch_data->dp;
|
||||
|
||||
/* work-item flattened absolute ID = ID0 + ID1 * max0 + ID2 * max0 * max1. */
|
||||
uint64_t id0 = __hsail_workitemabsid (0, context);
|
||||
uint64_t id1 = __hsail_workitemabsid (1, context);
|
||||
uint64_t id2 = __hsail_workitemabsid (2, context);
|
||||
|
||||
uint64_t max0 = dp->grid_size_x;
|
||||
uint64_t max1 = dp->grid_size_y;
|
||||
uint64_t id = id0 + id1 * max0 + id2 * max0 * max1;
|
||||
return (uint32_t) id;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_currentworkgroupsize (uint32_t dim, PHSAWorkItem *wi)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = wi->launch_data->dp;
|
||||
uint32_t wg_size = 0;
|
||||
switch (dim)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
if ((uint64_t) wi->wg->x < dp->grid_size_x / dp->workgroup_size_x)
|
||||
wg_size = dp->workgroup_size_x; /* Full WG. */
|
||||
else
|
||||
wg_size = dp->grid_size_x % dp->workgroup_size_x; /* Partial WG. */
|
||||
break;
|
||||
case 1:
|
||||
if ((uint64_t) wi->wg->y < dp->grid_size_y / dp->workgroup_size_y)
|
||||
wg_size = dp->workgroup_size_y; /* Full WG. */
|
||||
else
|
||||
wg_size = dp->grid_size_y % dp->workgroup_size_y; /* Partial WG. */
|
||||
break;
|
||||
case 2:
|
||||
if ((uint64_t) wi->wg->z < dp->grid_size_z / dp->workgroup_size_z)
|
||||
wg_size = dp->workgroup_size_z; /* Full WG. */
|
||||
else
|
||||
wg_size = dp->grid_size_z % dp->workgroup_size_z; /* Partial WG. */
|
||||
break;
|
||||
}
|
||||
return wg_size;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_workgroupsize (uint32_t dim, PHSAWorkItem *wi)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = wi->launch_data->dp;
|
||||
switch (dim)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
return dp->workgroup_size_x;
|
||||
case 1:
|
||||
return dp->workgroup_size_y;
|
||||
case 2:
|
||||
return dp->workgroup_size_z;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_gridsize (uint32_t dim, PHSAWorkItem *wi)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = wi->launch_data->dp;
|
||||
switch (dim)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
return dp->grid_size_x;
|
||||
case 1:
|
||||
return dp->grid_size_y;
|
||||
case 2:
|
||||
return dp->grid_size_z;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_workgroupid (uint32_t dim, PHSAWorkItem *wi)
|
||||
{
|
||||
switch (dim)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
return wi->wg->x;
|
||||
case 1:
|
||||
return wi->wg->y;
|
||||
case 2:
|
||||
return wi->wg->z;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_dim (PHSAWorkItem *wi)
|
||||
{
|
||||
hsa_kernel_dispatch_packet_t *dp = wi->launch_data->dp;
|
||||
return dp->setup & 0x3;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_packetid (PHSAWorkItem *wi)
|
||||
{
|
||||
return wi->launch_data->packet_id;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
__hsail_packetcompletionsig_sig32 (PHSAWorkItem *wi)
|
||||
{
|
||||
return (uint32_t) wi->launch_data->dp->completion_signal.handle;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
__hsail_packetcompletionsig_sig64 (PHSAWorkItem *wi)
|
||||
{
|
||||
return (uint64_t) (wi->launch_data->dp->completion_signal.handle);
|
||||
}
|
||||
|
||||
#ifdef HAVE_FIBERS
|
||||
void
|
||||
__hsail_barrier (PHSAWorkItem *wi)
|
||||
{
|
||||
fiber_barrier_reach ((fiber_barrier_t *) wi->launch_data->wg_sync_barrier);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return a 32b private segment address that points to a dynamically
|
||||
allocated chunk of 'size' with 'align'.
|
||||
|
||||
Allocates the space from the end of the private segment allocated
|
||||
for the whole work group. In implementations with separate private
|
||||
memories per WI, we will need to have a stack pointer per WI. But in
|
||||
the current implementation, the segment is shared, so we possibly
|
||||
save some space in case all WIs do not call the alloca.
|
||||
|
||||
The "alloca frames" are organized as follows:
|
||||
|
||||
wg->alloca_stack_p points to the last allocated data (initially
|
||||
outside the private segment)
|
||||
wg->alloca_frame_p points to the first address _outside_ the current
|
||||
function's allocations (initially to the same as alloca_stack_p)
|
||||
|
||||
The data is allocated downwards from the end of the private segment.
|
||||
|
||||
In the beginning of a new function which has allocas, a new alloca
|
||||
frame is pushed which adds the current alloca_frame_p (the current
|
||||
function's frame starting point) to the top of the alloca stack and
|
||||
alloca_frame_p is set to the current stack position.
|
||||
|
||||
At the exit points of a function with allocas, the alloca frame
|
||||
is popped before returning. This involves popping the alloca_frame_p
|
||||
to the one of the previous function in the call stack, and alloca_stack_p
|
||||
similarly, to the position of the last word alloca'd by the previous
|
||||
function.
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
__hsail_alloca (uint32_t size, uint32_t align, PHSAWorkItem *wi)
|
||||
{
|
||||
volatile PHSAWorkGroup *wg = wi->wg;
|
||||
uint32_t new_pos = wg->alloca_stack_p - size;
|
||||
while (new_pos % align != 0)
|
||||
new_pos--;
|
||||
wg->alloca_stack_p = new_pos;
|
||||
|
||||
#ifdef DEBUG_ALLOCA
|
||||
printf ("--- alloca (%u, %u) sp @%u fp @%u\n", size, align,
|
||||
wg->alloca_stack_p, wg->alloca_frame_p);
|
||||
#endif
|
||||
return new_pos;
|
||||
}
|
||||
|
||||
/* Initializes a new "alloca frame" in the private segment.
|
||||
This should be called at all the function entry points in case
|
||||
the function contains at least one call to alloca. */
|
||||
|
||||
void
|
||||
__hsail_alloca_push_frame (PHSAWorkItem *wi)
|
||||
{
|
||||
volatile PHSAWorkGroup *wg = wi->wg;
|
||||
|
||||
/* Store the alloca_frame_p without any alignment padding so
|
||||
we know exactly where the previous frame ended after popping
|
||||
it. */
|
||||
#ifdef DEBUG_ALLOCA
|
||||
printf ("--- push frame ");
|
||||
#endif
|
||||
uint32_t last_word_offs = __hsail_alloca (4, 1, wi);
|
||||
memcpy (wg->private_base_ptr + last_word_offs,
|
||||
(const void *) &wg->alloca_frame_p, 4);
|
||||
wg->alloca_frame_p = last_word_offs;
|
||||
|
||||
#ifdef DEBUG_ALLOCA
|
||||
printf ("--- sp @%u fp @%u\n", wg->alloca_stack_p, wg->alloca_frame_p);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Frees the current "alloca frame" and restores the frame
|
||||
pointer.
|
||||
This should be called at all the function return points in case
|
||||
the function contains at least one call to alloca. Restores the
|
||||
alloca stack to the condition it was before pushing the frame
|
||||
the last time. */
|
||||
void
|
||||
__hsail_alloca_pop_frame (PHSAWorkItem *wi)
|
||||
{
|
||||
volatile PHSAWorkGroup *wg = wi->wg;
|
||||
|
||||
wg->alloca_stack_p = wg->alloca_frame_p;
|
||||
memcpy (&wg->alloca_frame_p,
|
||||
(const void *) (wg->private_base_ptr + wg->alloca_frame_p), 4);
|
||||
/* Now frame_p points to the beginning of the previous function's
|
||||
frame and stack_p to its end. */
|
||||
|
||||
wg->alloca_stack_p += 4;
|
||||
|
||||
#ifdef DEBUG_ALLOCA
|
||||
printf ("--- pop frame sp @%u fp @%u\n", wg->alloca_stack_p,
|
||||
wg->alloca_frame_p);
|
||||
#endif
|
||||
}
|
68
libhsail-rt/target-config.h.in
Normal file
68
libhsail-rt/target-config.h.in
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* target-config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* The size of `int', as computed by sizeof. */
|
||||
#undef SIZEOF_INT
|
||||
|
||||
/* The size of `void*', as computed by sizeof. */
|
||||
#undef SIZEOF_VOIDP
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
Loading…
Add table
Reference in a new issue