aboutsummaryrefslogtreecommitdiff
path: root/gcc/jit/libgccjit.c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2020-11-12 17:28:17 -0500
committerDavid Malcolm <dmalcolm@redhat.com>2020-11-12 17:30:01 -0500
commit421d0d0f54294a7bf2872b3b2ac521ce0fa9869e (patch)
tree750ae2f9567352ed7762d896424c2194c324f208 /gcc/jit/libgccjit.c
parentfec573408310139e1ffc42741fbe46b4f2947592 (diff)
downloadgcc-421d0d0f54294a7bf2872b3b2ac521ce0fa9869e.zip
gcc-421d0d0f54294a7bf2872b3b2ac521ce0fa9869e.tar.gz
gcc-421d0d0f54294a7bf2872b3b2ac521ce0fa9869e.tar.bz2
jit: add support for inline asm [PR87291]
This patch adds various entrypoints to libgccjit for directly embedding asm statements into a compile, analogous to inline asm in the C frontend: gcc_jit_block_add_extended_asm gcc_jit_block_end_with_extended_asm_goto gcc_jit_extended_asm_as_object gcc_jit_extended_asm_set_volatile_flag gcc_jit_extended_asm_set_inline_flag gcc_jit_extended_asm_add_output_operand gcc_jit_extended_asm_add_input_operand gcc_jit_extended_asm_add_clobber gcc_jit_context_add_top_level_asm gcc/jit/ChangeLog: PR jit/87291 * docs/cp/topics/asm.rst: New file. * docs/cp/topics/index.rst (Topic Reference): Add it. * docs/topics/asm.rst: New file. * docs/topics/compatibility.rst (LIBGCCJIT_ABI_15): New. * docs/topics/functions.rst (Statements): Add link to extended asm. * docs/topics/index.rst (Topic Reference): Add asm.rst. * docs/topics/objects.rst: Add gcc_jit_extended_asm to ASCII art. * docs/_build/texinfo/Makefile: Regenerate. * docs/_build/texinfo/libgccjit.texi: Regenerate. * jit-common.h (gcc::jit::recording::extended_asm): New forward decl. (gcc::jit::recording::top_level_asm): Likewise. * jit-playback.c: Include "stmt.h". (build_string): New. (gcc::jit::playback::context::new_string_literal): Disambiguate build_string call. (gcc::jit::playback::context::add_top_level_asm): New. (build_operand_chain): New. (build_clobbers): New. (build_goto_operands): New. (gcc::jit::playback::block::add_extended_asm): New. * jit-playback.h (gcc::jit::playback::context::add_top_level_asm): New decl. (struct gcc::jit::playback::asm_operand): New struct. (gcc::jit::playback::block::add_extended_asm): New decl. * jit-recording.c (gcc::jit::recording::context::dump_to_file): Dump top-level asms. (gcc::jit::recording::context::add_top_level_asm): New. (gcc::jit::recording::block::add_extended_asm): New. (gcc::jit::recording::block::end_with_extended_asm_goto): New. (gcc::jit::recording::asm_operand::asm_operand): New. (gcc::jit::recording::asm_operand::print): New. (gcc::jit::recording::asm_operand::make_debug_string): New. (gcc::jit::recording::output_asm_operand::write_reproducer): New. (gcc::jit::recording::output_asm_operand::print): New. (gcc::jit::recording::input_asm_operand::write_reproducer): New. (gcc::jit::recording::input_asm_operand::print): New. (gcc::jit::recording::extended_asm::add_output_operand): New. (gcc::jit::recording::extended_asm::add_input_operand): New. (gcc::jit::recording::extended_asm::add_clobber): New. (gcc::jit::recording::extended_asm::replay_into): New. (gcc::jit::recording::extended_asm::make_debug_string): New. (gcc::jit::recording::extended_asm::write_flags): New. (gcc::jit::recording::extended_asm::write_clobbers): New. (gcc::jit::recording::extended_asm_simple::write_reproducer): New. (gcc::jit::recording::extended_asm::maybe_populate_playback_blocks): New. (gcc::jit::recording::extended_asm_goto::extended_asm_goto): New. (gcc::jit::recording::extended_asm_goto::replay_into): New. (gcc::jit::recording::extended_asm_goto::write_reproducer): New. (gcc::jit::recording::extended_asm_goto::get_successor_blocks): New. (gcc::jit::recording::extended_asm_goto::maybe_print_gotos): New. (gcc::jit::recording::extended_asm_goto::maybe_populate_playback_blocks): New. (gcc::jit::recording::top_level_asm::top_level_asm): New. (gcc::jit::recording::top_level_asm::replay_into): New. (gcc::jit::recording::top_level_asm::make_debug_string): New. (gcc::jit::recording::top_level_asm::write_to_dump): New. (gcc::jit::recording::top_level_asm::write_reproducer): New. * jit-recording.h (gcc::jit::recording::context::add_top_level_asm): New decl. (gcc::jit::recording::context::m_top_level_asms): New field. (gcc::jit::recording::block::add_extended_asm): New decl. (gcc::jit::recording::block::end_with_extended_asm_goto): New decl. (gcc::jit::recording::asm_operand): New class. (gcc::jit::recording::output_asm_operand): New class. (gcc::jit::recording::input_asm_operand): New class. (gcc::jit::recording::extended_asm): New class. (gcc::jit::recording::extended_asm_simple): New class. (gcc::jit::recording::extended_asm_goto): New class. (gcc::jit::recording::top_level_asm): New class. * libgccjit++.h (gccjit::extended_asm): New forward decl. (gccjit::context::add_top_level_asm): New. (gccjit::block::add_extended_asm): New. (gccjit::block::end_with_extended_asm_goto): New. (gccjit::extended_asm): New class. (gccjit::extended_asm::extended_asm): New ctors. (gccjit::extended_asm::set_volatile_flag): New. (gccjit::extended_asm::set_inline_flag): New. (gccjit::extended_asm::add_output_operand): New. (gccjit::extended_asm::add_input_operand): New. (gccjit::extended_asm::add_clobber): New. (gccjit::extended_asm::get_inner_extended_asm): New. * libgccjit.c (struct gcc_jit_extended_asm): New. (jit_error): Make "loc" param take a gcc::jit::recording::location * rather than a gcc_jit_location *. (gcc_jit_block_add_extended_asm): New entrypoint. (gcc_jit_block_end_with_extended_asm_goto): New entrypoint. (gcc_jit_extended_asm_as_object): New entrypoint. (gcc_jit_extended_asm_set_volatile_flag): New entrypoint. (gcc_jit_extended_asm_set_inline_flag): New entrypoint. (gcc_jit_extended_asm_add_output_operand): New entrypoint. (gcc_jit_extended_asm_add_clobber): New entrypoint. (gcc_jit_context_add_top_level_asm): New entrypoint. * libgccjit.h: Add gcc_jit_extended_asm to ASCII art. (gcc_jit_extended_asm): New typedef. (LIBGCCJIT_HAVE_ASM_STATEMENTS): New define. (gcc_jit_block_add_extended_asm): New entrypoint. (gcc_jit_block_end_with_extended_asm_goto): New entrypoint. (gcc_jit_extended_asm_as_object): New entrypoint. (gcc_jit_extended_asm_set_volatile_flag): New entrypoint. (gcc_jit_extended_asm_set_inline_flag): New entrypoint. (gcc_jit_extended_asm_add_output_operand): New entrypoint. (gcc_jit_extended_asm_add_input_operand): New entrypoint. (gcc_jit_extended_asm_add_clobber): New entrypoint. (gcc_jit_context_add_top_level_asm): New entrypoint. * libgccjit.map (LIBGCCJIT_ABI_15): New. gcc/testsuite/ChangeLog: PR jit/87291 * jit.dg/jit.exp: Load target-supports-dg.exp. Set dg-do-what-default. (jit-dg-test): Set dg-do-what and call dg-get-options, skipping the test if it's not supported on the given target. * jit.dg/test-asm.c: New test. * jit.dg/test-asm.cc: New test.
Diffstat (limited to 'gcc/jit/libgccjit.c')
-rw-r--r--gcc/jit/libgccjit.c188
1 files changed, 186 insertions, 2 deletions
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index a00aefc..f9c33c6 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -96,6 +96,11 @@ struct gcc_jit_timer : public timer
{
};
+struct gcc_jit_extended_asm : public gcc::jit::recording::extended_asm
+{
+};
+
+
/**********************************************************************
Error-handling.
@@ -300,13 +305,13 @@ struct gcc_jit_timer : public timer
static void
jit_error (gcc::jit::recording::context *ctxt,
- gcc_jit_location *loc,
+ gcc::jit::recording::location *loc,
const char *fmt, ...)
GNU_PRINTF(3, 4);
static void
jit_error (gcc::jit::recording::context *ctxt,
- gcc_jit_location *loc,
+ gcc::jit::recording::location *loc,
const char *fmt, ...)
{
va_list ap;
@@ -3290,3 +3295,182 @@ gcc_jit_version_patchlevel (void)
version_info vi;
return vi.patchlevel;
}
+
+/**********************************************************************
+ Asm support.
+ **********************************************************************/
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::block::add_extended_asm, in
+ jit-recording.c. */
+
+gcc_jit_extended_asm *
+gcc_jit_block_add_extended_asm (gcc_jit_block *block,
+ gcc_jit_location *loc,
+ const char *asm_template)
+{
+ RETURN_NULL_IF_NOT_VALID_BLOCK (block, loc);
+ gcc::jit::recording::context *ctxt = block->get_context ();
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ /* LOC can be NULL. */
+ RETURN_NULL_IF_FAIL (asm_template, ctxt, loc, "NULL asm_template");
+
+ return (gcc_jit_extended_asm *)block->add_extended_asm (loc, asm_template);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::block::end_with_extended_asm_goto, in
+ jit-recording.c. */
+
+gcc_jit_extended_asm *
+gcc_jit_block_end_with_extended_asm_goto (gcc_jit_block *block,
+ gcc_jit_location *loc,
+ const char *asm_template,
+ int num_goto_blocks,
+ gcc_jit_block **goto_blocks,
+ gcc_jit_block *fallthrough_block)
+{
+ RETURN_NULL_IF_NOT_VALID_BLOCK (block, loc);
+ gcc::jit::recording::context *ctxt = block->get_context ();
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ /* LOC can be NULL. */
+ RETURN_NULL_IF_FAIL (asm_template, ctxt, loc, "NULL asm_template");
+ RETURN_NULL_IF_FAIL (num_goto_blocks >= 0, ctxt, loc, "num_goto_blocks < 0");
+ for (int i = 0; i < num_goto_blocks; i++)
+ RETURN_NULL_IF_FAIL_PRINTF1 (goto_blocks[i],
+ ctxt, loc,
+ "NULL goto_blocks[%i]", i);
+ /* fallthrough_block can be NULL. */
+ return (gcc_jit_extended_asm *)block->end_with_extended_asm_goto
+ (loc, asm_template,
+ num_goto_blocks, (gcc::jit::recording::block **)goto_blocks,
+ fallthrough_block);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, this calls the trivial
+ gcc::jit::recording::memento::as_object method (an extended_asm is a
+ memento), in jit-recording.h. */
+
+gcc_jit_object *
+gcc_jit_extended_asm_as_object (gcc_jit_extended_asm *ext_asm)
+{
+ RETURN_NULL_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+
+ return static_cast <gcc_jit_object *> (ext_asm->as_object ());
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::extended_asm::set_volatile_flag, in
+ jit-recording.c. */
+
+void
+gcc_jit_extended_asm_set_volatile_flag (gcc_jit_extended_asm *ext_asm,
+ int flag)
+{
+ RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+ ext_asm->set_volatile_flag (flag);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::extended_asm::set_inline_flag, in
+ jit-recording.c. */
+
+void
+gcc_jit_extended_asm_set_inline_flag (gcc_jit_extended_asm *ext_asm,
+ int flag)
+{
+ RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+ ext_asm->set_inline_flag (flag);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::extended_asm::add_output_operand, in
+ jit-recording.c. */
+
+void
+gcc_jit_extended_asm_add_output_operand (gcc_jit_extended_asm *ext_asm,
+ const char *asm_symbolic_name,
+ const char *constraint,
+ gcc_jit_lvalue *dest)
+{
+ RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+ gcc::jit::recording::context *ctxt = ext_asm->get_context ();
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ gcc::jit::recording::location *loc = ext_asm->get_loc ();
+ /* asm_symbolic_name can be NULL. */
+ RETURN_IF_FAIL (constraint, ctxt, loc, "NULL constraint");
+ RETURN_IF_FAIL (dest, ctxt, loc, "NULL dest");
+ RETURN_IF_FAIL (!ext_asm->is_goto (), ctxt, loc,
+ "cannot add output operand to asm goto");
+ ext_asm->add_output_operand (asm_symbolic_name, constraint, dest);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::extended_asm::add_input_operand, in
+ jit-recording.c. */
+
+extern void
+gcc_jit_extended_asm_add_input_operand (gcc_jit_extended_asm *ext_asm,
+ const char *asm_symbolic_name,
+ const char *constraint,
+ gcc_jit_rvalue *src)
+{
+ RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+ gcc::jit::recording::context *ctxt = ext_asm->get_context ();
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ gcc::jit::recording::location *loc = ext_asm->get_loc ();
+ /* asm_symbolic_name can be NULL. */
+ RETURN_IF_FAIL (constraint, ctxt, loc, "NULL constraint");
+ RETURN_IF_FAIL (src, ctxt, loc, "NULL src");
+ ext_asm->add_input_operand (asm_symbolic_name, constraint, src);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::extended_asm::add_clobber, in
+ jit-recording.c. */
+
+void
+gcc_jit_extended_asm_add_clobber (gcc_jit_extended_asm *ext_asm,
+ const char *victim)
+{
+ RETURN_IF_FAIL (ext_asm, NULL, NULL, "NULL ext_asm");
+ gcc::jit::recording::context *ctxt = ext_asm->get_context ();
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ gcc::jit::recording::location *loc = ext_asm->get_loc ();
+ RETURN_IF_FAIL (victim, ctxt, loc, "NULL victim");
+ ext_asm->add_clobber (victim);
+}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is done by the
+ gcc::jit::recording::context::add_top_level_asm, in
+ jit-recording.c. */
+
+void
+gcc_jit_context_add_top_level_asm (gcc_jit_context *ctxt,
+ gcc_jit_location *loc,
+ const char *asm_stmts)
+{
+ RETURN_IF_FAIL (ctxt, NULL, NULL, "NULL ctxt");
+ JIT_LOG_FUNC (ctxt->get_logger ());
+ /* LOC can be NULL. */
+ RETURN_IF_FAIL (asm_stmts, ctxt, NULL, "NULL asm_stmts");
+ ctxt->add_top_level_asm (loc, asm_stmts);
+}