diff options
author | David Malcolm <dmalcolm@redhat.com> | 2020-11-12 17:28:17 -0500 |
---|---|---|
committer | David Malcolm <dmalcolm@redhat.com> | 2020-11-12 17:30:01 -0500 |
commit | 421d0d0f54294a7bf2872b3b2ac521ce0fa9869e (patch) | |
tree | 750ae2f9567352ed7762d896424c2194c324f208 /gcc/jit/libgccjit.c | |
parent | fec573408310139e1ffc42741fbe46b4f2947592 (diff) | |
download | gcc-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.c | 188 |
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); +} |