From 51371b45d6db0ae2e4fadc7a132dc1e1bf8a35dd Mon Sep 17 00:00:00 2001 From: Robert Pengelly Date: Wed, 16 Sep 2026 16:16:59 +0100 Subject: [PATCH] Fixed GCC-style in instruction handling in inline assembly --- amd64.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- i386.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 118 insertions(+), 8 deletions(-) diff --git a/amd64.c b/amd64.c index 1a1b049..b359810 100644 --- a/amd64.c +++ b/amd64.c @@ -33302,6 +33302,21 @@ static int inline_asm_template_is_out (const char *templ) { } +static int inline_asm_template_is_in (const char *templ) { + + if (!templ) { + return 0; + } + + while (*templ == ' ' || *templ == '\t') { + templ++; + } + + return strncmp (templ, "inb ", 4) == 0 || strncmp (templ, "inw ", 4) == 0 || + strncmp (templ, "inl ", 4) == 0 || strncmp (templ, "in ", 3) == 0; + +} + static int inline_asm_out_operand_size (const char *templ, const char *constraint) { if (!templ || !constraint) { @@ -33597,12 +33612,12 @@ static void inline_asm_emit_input_load (const char *constraint, int input_index, } - if (inline_asm_template_is_out (templ)) { + if (inline_asm_template_is_out (templ) || inline_asm_template_is_in (templ)) { /** * GCC's "N" constraint is really an 8-bit immediate port. - * For the OUT templates, allow a non-constant here as a - * convenience and lower it through DX, because x86 OUT cannot + * For the IN/OUT templates, allow a non-constant here as a + * convenience and lower it through DX, because x86 IN/OUT cannot * encode a variable port as an immediate. */ emit_load_assignment_rhs_expression_to_reg ("rdx"); @@ -33641,7 +33656,7 @@ static void inline_asm_emit_input_load (const char *constraint, int input_index, inputs[input_index].size = inline_asm_identifier_size (tok.ident); } - if (inline_asm_template_is_out (templ)) { + if (inline_asm_template_is_out (templ) || inline_asm_template_is_in (templ)) { int out_size = inline_asm_out_operand_size (templ, constraint); @@ -33869,6 +33884,46 @@ static void inline_asm_emit_template (const char *templ, struct inline_asm_input } + if ((strncmp (line, "inb ", 4) == 0 || strncmp (line, "inw ", 4) == 0 || strncmp (line, "inl ", 4) == 0 || strncmp (line, "in ", 3) == 0)) { + + char *args; + char *comma; + char *lhs; + char *rhs; + + args = strchr (line, ' '); + + if (args) { + + args++; + comma = strchr (args, ','); + + if (comma) { + + *comma = 0; + + lhs = args; + rhs = comma + 1; + + while (*lhs == ' ' || *lhs == '\t') { + lhs++; + } + + while (*rhs == ' ' || *rhs == '\t') { + rhs++; + } + + fprintf (state->ofp, " in %s, %s\n", rhs, lhs); + inline_asm_finish_operands (inputs, input_count); + + return; + + } + + } + + } + if (line[0]) { inline_asm_rewrite_narrow_movzx (line, sizeof (line)); diff --git a/i386.c b/i386.c index 7943747..39b62fc 100644 --- a/i386.c +++ b/i386.c @@ -30605,6 +30605,21 @@ static int inline_asm_template_is_out (const char *templ) { } +static int inline_asm_template_is_in (const char *templ) { + + if (!templ) { + return 0; + } + + while (*templ == ' ' || *templ == '\t') { + templ++; + } + + return strncmp (templ, "inb ", 4) == 0 || strncmp (templ, "inw ", 4) == 0 || + strncmp (templ, "inl ", 4) == 0 || strncmp (templ, "in ", 3) == 0; + +} + static int inline_asm_out_operand_size (const char *templ, const char *constraint) { if (!templ || !constraint) { @@ -30900,12 +30915,12 @@ static void inline_asm_emit_input_load (const char *constraint, int input_index, } - if (inline_asm_template_is_out (templ)) { + if (inline_asm_template_is_out (templ) || inline_asm_template_is_in (templ)) { /** * GCC's "N" constraint is really an 8-bit immediate port. - * For the OUT templates, allow a non-constant here as a - * convenience and lower it through DX, because x86 OUT cannot + * For the IN/OUT templates, allow a non-constant here as a + * convenience and lower it through DX, because x86 IN/OUT cannot * encode a variable port as an immediate. */ emit_load_assignment_rhs_expression_to_reg ("edx"); @@ -30944,7 +30959,7 @@ static void inline_asm_emit_input_load (const char *constraint, int input_index, inputs[input_index].size = inline_asm_identifier_size (tok.ident); } - if (inline_asm_template_is_out (templ)) { + if (inline_asm_template_is_out (templ) || inline_asm_template_is_in (templ)) { int out_size = inline_asm_out_operand_size (templ, constraint); @@ -31168,6 +31183,46 @@ static void inline_asm_emit_template (const char *templ, struct inline_asm_input } + if ((strncmp (line, "inb ", 4) == 0 || strncmp (line, "inw ", 4) == 0 || strncmp (line, "inl ", 4) == 0 || strncmp (line, "in ", 3) == 0)) { + + char *args; + char *comma; + char *lhs; + char *rhs; + + args = strchr (line, ' '); + + if (args) { + + args++; + comma = strchr (args, ','); + + if (comma) { + + *comma = 0; + + lhs = args; + rhs = comma + 1; + + while (*lhs == ' ' || *lhs == '\t') { + lhs++; + } + + while (*rhs == ' ' || *rhs == '\t') { + rhs++; + } + + fprintf (state->ofp, " in %s, %s\n", rhs, lhs); + inline_asm_finish_operands (inputs, input_count); + + return; + + } + + } + + } + if (line[0]) { inline_asm_rewrite_narrow_movzx (line, sizeof (line)); -- 2.34.1