[PATCH 2/2] x86: permit non-immediate offset operands with direct far branches
H.J. Lu
hjl.tools@gmail.com
Mon Oct 14 06:50:44 GMT 2024
On Mon, Oct 14, 2024, 2:39 PM Jan Beulich <jbeulich@suse.com> wrote:
> While Intel syntax permits such already (as can be observed by there
> not being a need to prefix the respective operand with "offset"), AT&T
> syntax so far strictly insists on two immediate operands. Multiple
> (successive) immediate operands are somewhat problematic anyway, as
> it's never really clear what their order ought to be. While there's no
> apparent way of dealing with this for ENTER, EXTRQ, and INSERTQ, for
> LCALL and LJMP we can aid programmers by permitting alternative forms,
> with the offset operand being a "displacement" rather than an
> "immediate". The order of the two operands the doesn't matter; they're
> distinguished by type.
>
> Mark the new templates AT&T-only; the original ones really should have
> been so, too. For backwards compatibility reasons we can't really
> correct that mistake ...
> ---
> While the proper Intel syntax operand form is sel:offset, for some
> reason we also support two (comma separated) operands. The ambiguity
> there is being left alone, as the sel:offset form is enough to avoid it.
>
I don't think this is a good idea. $ is used to denote an immediate
operand in
AT&T syntax. This change serves no practical purposes for programmers.
> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -7061,13 +7061,16 @@ i386_assemble (char *line)
> swap_operands ();
>
> /* The order of the immediates should be reversed for 2-immediates EXTRQ
> - and INSERTQ instructions. Also UWRMSR wants its immediate to be in
> the
> - "canonical" place (first), despite it appearing last (in AT&T
> syntax, or
> - because of the swapping above) in the incoming set of operands. */
> + and INSERTQ instructions. Also direct far branches and UWRMSR want
> their
> + immediate to be in the "canonical" place (first), despite it
> (possibly)
> + appearing last (in AT&T syntax, or because of the swapping above) in
> the
> + incoming set of operands. */
> if ((i.imm_operands == 2
> && (t->mnem_off == MN_extrq || t->mnem_off == MN_insertq))
> - || (t->mnem_off == MN_uwrmsr && i.imm_operands
> - && i.operands > i.imm_operands))
> + || (((t->opcode_modifier.jump == JUMP_INTERSEGMENT
> + && !operand_type_check (i.types[0], imm))
> + || t->mnem_off == MN_uwrmsr)
> + && i.imm_operands && i.operands > i.imm_operands))
> swap_2_operands (0, 1);
>
> if (i.imm_operands)
> @@ -11621,6 +11624,7 @@ output_interseg_jump (void)
> int size;
> int prefix;
> int code16;
> + const expressionS *exp1;
>
> code16 = 0;
> if (flag_code == CODE_16BIT)
> @@ -11659,9 +11663,11 @@ output_interseg_jump (void)
> *p++ = i.prefix[REX_PREFIX];
>
> *p++ = i.tm.base_opcode;
> - if (i.op[1].imms->X_op == O_constant)
> + exp1 = operand_type_check (i.types[0], imm) ? i.op[1].imms
> + : i.op[1].disps;
> + if (exp1->X_op == O_constant)
> {
> - offsetT n = i.op[1].imms->X_add_number;
> + offsetT n = exp1->X_add_number;
>
> if (size == 2
> && !fits_in_unsigned_word (n)
> @@ -11674,7 +11680,7 @@ output_interseg_jump (void)
> }
> else
> fix_new_exp (frag_now, p - frag_now->fr_literal, size,
> - i.op[1].imms, 0, reloc (size, 0, 0, i.reloc[1]));
> + exp1, 0, reloc (size, 0, 0, i.reloc[1]));
>
> p += size;
> if (i.op[0].imms->X_op == O_constant)
> --- a/gas/testsuite/gas/i386/jump.d
> +++ b/gas/testsuite/gas/i386/jump.d
> @@ -15,28 +15,32 @@ Disassembly of section .text:
> [ ]*[a-f0-9]+: 66 ff 2c bd 00 00 00 00 ljmpw
> \*0x0\(,%edi,4\) 1c: (R_386_)?(dir)?32 xxx
> [ ]*[a-f0-9]+: ff 2d 00 00 00 00 ljmp \*0x0 22:
> (R_386_)?(dir)?32 xxx
> [ ]*[a-f0-9]+: 66 ff 2d 00 00 00 00 ljmpw \*0x0 29:
> (R_386_)?(dir)?32 xxx
> -[ ]*[a-f0-9]+: ea 00 00 00 00 34 12 ljmp \$0x1234,\$0x0
> 2e: (R_386_)?(dir)?32 xxx
> -[ ]*[a-f0-9]+: e8 c7 ff ff ff call (0x0|0 <.text>)
> -[ ]*[a-f0-9]+: e8 ((fc|c2) ff ff ff|00 00 00 00)
> call (0x)?(0|3a|3e)( <.text(\+0x3e)?>)? 3a: (R_386_PC)?(DISP)?32
> xxx
> -[ ]*[a-f0-9]+: ff 15 00 00 00 00 call \*0x0 40:
> (R_386_)?(dir)?32 xxx
> +[ ]*[a-f0-9]+: ea 00 00 00 00 34 12 ljmp \$0x1234,\$0x0[
> ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> +[ ]*[a-f0-9]+: ea 00 00 00 00 34 12 ljmp \$0x1234,\$0x0[
> ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> +[ ]*[a-f0-9]+: ea 00 00 00 00 34 12 ljmp \$0x1234,\$0x0[
> ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> +[ ]*[a-f0-9]+: e8 b9 ff ff ff call (0x0|0 <.text>)
> +[ ]*[a-f0-9]+: e8 ((fc|b4) ff ff ff|00 00 00 00)
> call (0x)?(0|48|4c)( <.text(\+0x4c)?>)?[ ]+[a-f0-9]+:
> (R_386_PC|DISP)32 xxx
> +[ ]*[a-f0-9]+: ff 15 00 00 00 00 call \*0x0[
> ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> [ ]*[a-f0-9]+: ff d7 call \*%edi
> [ ]*[a-f0-9]+: ff 17 call \*\(%edi\)
> -[ ]*[a-f0-9]+: ff 1c bd 00 00 00 00 lcall \*0x0\(,%edi,4\)
> 4b: (R_386_)?(dir)?32 xxx
> -[ ]*[a-f0-9]+: 66 ff 1c bd 00 00 00 00 lcallw
> \*0x0\(,%edi,4\) 53: (R_386_)?(dir)?32 xxx
> -[ ]*[a-f0-9]+: ff 1d 00 00 00 00 lcall \*0x0 59:
> (R_386_)?(dir)?32 xxx
> -[ ]*[a-f0-9]+: 66 ff 1d 00 00 00 00 lcallw \*0x0 60:
> (R_386_)?(dir)?32 xxx
> -[ ]*[a-f0-9]+: 9a 00 00 00 00 34 12 lcall \$0x1234,\$0x0
> 65: (R_386_)?(dir)?32 xxx
> +[ ]*[a-f0-9]+: ff 1c bd 00 00 00 00 lcall \*0x0\(,%edi,4\)[
> ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> +[ ]*[a-f0-9]+: 66 ff 1c bd 00 00 00 00 lcallw
> \*0x0\(,%edi,4\)[ ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> +[ ]*[a-f0-9]+: ff 1d 00 00 00 00 lcall \*0x0[
> ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> +[ ]*[a-f0-9]+: 66 ff 1d 00 00 00 00 lcallw \*0x0[
> ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> +[ ]*[a-f0-9]+: 9a 00 00 00 00 34 12 lcall \$0x1234,\$0x0[
> ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> +[ ]*[a-f0-9]+: 9a 00 00 00 00 34 12 lcall \$0x1234,\$0x0[
> ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> +[ ]*[a-f0-9]+: 9a 00 00 00 00 34 12 lcall \$0x1234,\$0x0[
> ]+[a-f0-9]+: (R_386_|dir)?32 xxx
> [ ]*[a-f0-9]+: 66 ff 13 callw \*\(%ebx\)
> [ ]*[a-f0-9]+: ff 13 call \*\(%ebx\)
> [ ]*[a-f0-9]+: ff 1b lcall \*\(%ebx\)
> [ ]*[a-f0-9]+: 66 ff 23 jmpw \*\(%ebx\)
> [ ]*[a-f0-9]+: ff 23 jmp \*\(%ebx\)
> [ ]*[a-f0-9]+: ff 2b ljmp \*\(%ebx\)
> -[ ]*[a-f0-9]+: eb 00 jmp (0x)?7b(
> <.text(\+0x7b)?>)?
> +[ ]*[a-f0-9]+: eb 00 jmp (0x)?97(
> <.text(\+0x97)?>)?
> [ ]*[a-f0-9]+: 90 nop
> -[ ]*[a-f0-9]+: e3 00 jecxz (0x)?7e(
> <.text(\+0x7e)?>)?
> +[ ]*[a-f0-9]+: e3 00 jecxz (0x)?9a(
> <.text(\+0x9a)?>)?
> [ ]*[a-f0-9]+: 90 nop
> -[ ]*[a-f0-9]+: eb 00 jmp (0x)?81(
> <.text(\+0x81)?>)?
> +[ ]*[a-f0-9]+: eb 00 jmp (0x)?9d(
> <.text(\+0x9d)?>)?
> [ ]*[a-f0-9]+: 90 nop
> [ ]*[a-f0-9]+: 9a 90 90 90 90 90 90 lcall
> \$0x9090,\$0x90909090
> [ ]*[a-f0-9]+: 9a 90 90 90 90 90 90 lcall
> \$0x9090,\$0x90909090
> --- a/gas/testsuite/gas/i386/jump.s
> +++ b/gas/testsuite/gas/i386/jump.s
> @@ -13,6 +13,8 @@
> ljmp *xxx
> ljmpw *xxx
> ljmp $0x1234,$xxx
> + ljmp $0x1234,xxx
> + ljmp xxx,$0x1234
>
> call 1b
> call xxx
> @@ -24,6 +26,8 @@
> lcall *xxx
> lcallw *xxx
> lcall $0x1234,$xxx
> + lcall $0x1234,xxx
> + lcall xxx,$0x1234
>
> .intel_syntax noprefix
> call word ptr [ebx]
> --- a/opcodes/i386-opc.tbl
> +++ b/opcodes/i386-opc.tbl
> @@ -494,6 +494,7 @@ call, 0x9a, No64, JumpInterSegment|Impli
> call, 0xff/3, 0,
> Amd64|Modrm|JumpAbsolute|ImplicitStackOp|DefaultSize|NoSuf, {
> Dword|Fword|BaseIndex }
> call, 0xff/3, x64, Intel64|Modrm|JumpAbsolute|ImplicitStackOp|NoSuf, {
> Dword|Fword|Tbyte|BaseIndex }
> lcall, 0x9a, No64, JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|No_qSuf,
> { Imm16, Imm16|Imm32 }
> +lcall, 0x9a, No64,
> JumpInterSegment|DefaultSize|No_bSuf|No_sSuf|No_qSuf|ATTSyntax, { Imm16,
> Disp16|Disp32 }
> lcall, 0xff/3, 0,
> Amd64|Modrm|JumpAbsolute|DefaultSize|No_bSuf|No_sSuf|No_qSuf, {
> Unspecified|BaseIndex }
> lcall, 0xff/3, x64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_sSuf, {
> Unspecified|BaseIndex }
>
> @@ -507,6 +508,7 @@ jmp, 0xea, No64, JumpInterSegment|No_bSu
> jmp, 0xff/5, 0, Amd64|Modrm|JumpAbsolute|NoSuf, { Dword|Fword|BaseIndex }
> jmp, 0xff/5, x64, Intel64|Modrm|JumpAbsolute|NoSuf, {
> Dword|Fword|Tbyte|BaseIndex }
> ljmp, 0xea, No64, JumpInterSegment|No_bSuf|No_sSuf|No_qSuf, { Imm16,
> Imm16|Imm32 }
> +ljmp, 0xea, No64, JumpInterSegment|No_bSuf|No_sSuf|No_qSuf|ATTSyntax, {
> Imm16, Disp16|Disp32 }
> ljmp, 0xff/5, 0, Amd64|Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf, {
> Unspecified|BaseIndex }
> ljmp, 0xff/5, x64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_sSuf, {
> Unspecified|BaseIndex }
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://sourceware.org/pipermail/binutils/attachments/20241014/e6e2a8f4/attachment-0001.htm>
More information about the Binutils
mailing list