Message ID | 20140127194457.GA12183@intel.com |
---|---|
State | New |
Headers | show |
On Mon, Jan 27, 2014 at 8:44 PM, H.J. Lu <hongjiu.lu@intel.com> wrote: > The .code16gcc directive was added to binutils back in 1999: > > --- > '.code16gcc' provides experimental support for generating 16-bit code > from gcc, and differs from '.code16' in that 'call', 'ret', 'enter', > 'leave', 'push', 'pop', 'pusha', 'popa', 'pushf', and 'popf' > instructions default to 32-bit size. This is so that the stack pointer > is manipulated in the same way over function calls, allowing access to > function parameters at the same stack offsets as in 32-bit mode. > '.code16gcc' also automatically adds address size prefixes where > necessary to use the 32-bit addressing modes that gcc generates. > --- > > It encodes 32-bit assembly instructions generated by GCC in 16-bit format > so that GCC can be used to generate 16-bit instructions. To do that, the > .code16gcc directive may be placed at the very beginning of the assembly > code. This patch adds -m16 to x86 backend by: > > 1. Add -m16 and make it mutually exclusive with -m32, -m64 and -mx32. > 2. Treat -m16 like -m32 so that --32 is passed to assembler. > 3. Output .code16gcc at the very beginning of the assembly code. > 4. Turn off 64-bit ISA when -m16 is used. > > Tested on Linux/x86 and Linux/x86-64. OK for trunk? > > Thanks. > > H.J. > --- > PR target/59672 > * config/i386/gnu-user64.h (SPEC_32): Add "m16|" to "m32". > (SPEC_X32): Likewise. > (SPEC_64): Likewise. > * config/i386/i386.c (ix86_option_override_internal): Turn off > OPTION_MASK_ISA_64BIT, OPTION_MASK_ABI_X32 and OPTION_MASK_ABI_64 > for TARGET_16BIT. > (x86_file_start): Output .code16gcc for TARGET_16BIT. > * config/i386/i386.h (TARGET_16BIT): New macro. > (TARGET_16BIT_P): Likewise. > * config/i386/i386.opt: Add m16. > * doc/invoke.texi: Document -m16. OK for mainline, needs OK from RMs for a backport. Please also add the entry to Changes.html, this is user-visible change. Thanks, Uros.
On Tue, Jan 28, 2014 at 5:01 PM, Uros Bizjak <ubizjak@gmail.com> wrote: > On Mon, Jan 27, 2014 at 8:44 PM, H.J. Lu <hongjiu.lu@intel.com> wrote: > >> The .code16gcc directive was added to binutils back in 1999: >> >> --- >> '.code16gcc' provides experimental support for generating 16-bit code >> from gcc, and differs from '.code16' in that 'call', 'ret', 'enter', >> 'leave', 'push', 'pop', 'pusha', 'popa', 'pushf', and 'popf' >> instructions default to 32-bit size. This is so that the stack pointer >> is manipulated in the same way over function calls, allowing access to >> function parameters at the same stack offsets as in 32-bit mode. >> '.code16gcc' also automatically adds address size prefixes where >> necessary to use the 32-bit addressing modes that gcc generates. >> --- >> >> It encodes 32-bit assembly instructions generated by GCC in 16-bit format >> so that GCC can be used to generate 16-bit instructions. To do that, the >> .code16gcc directive may be placed at the very beginning of the assembly >> code. This patch adds -m16 to x86 backend by: >> >> 1. Add -m16 and make it mutually exclusive with -m32, -m64 and -mx32. >> 2. Treat -m16 like -m32 so that --32 is passed to assembler. >> 3. Output .code16gcc at the very beginning of the assembly code. >> 4. Turn off 64-bit ISA when -m16 is used. >> >> Tested on Linux/x86 and Linux/x86-64. OK for trunk? >> >> Thanks. >> >> H.J. >> --- >> PR target/59672 >> * config/i386/gnu-user64.h (SPEC_32): Add "m16|" to "m32". >> (SPEC_X32): Likewise. >> (SPEC_64): Likewise. >> * config/i386/i386.c (ix86_option_override_internal): Turn off >> OPTION_MASK_ISA_64BIT, OPTION_MASK_ABI_X32 and OPTION_MASK_ABI_64 >> for TARGET_16BIT. >> (x86_file_start): Output .code16gcc for TARGET_16BIT. >> * config/i386/i386.h (TARGET_16BIT): New macro. >> (TARGET_16BIT_P): Likewise. >> * config/i386/i386.opt: Add m16. >> * doc/invoke.texi: Document -m16. > > OK for mainline, needs OK from RMs for a backport. > > Please also add the entry to Changes.html, this is user-visible change. Oh, a short scan-asm testcase would be nice, too. Thanks, Uros.
On Tue, 28 Jan 2014, Uros Bizjak wrote: > On Mon, Jan 27, 2014 at 8:44 PM, H.J. Lu <hongjiu.lu@intel.com> wrote: > > > The .code16gcc directive was added to binutils back in 1999: > > > > --- > > '.code16gcc' provides experimental support for generating 16-bit code > > from gcc, and differs from '.code16' in that 'call', 'ret', 'enter', > > 'leave', 'push', 'pop', 'pusha', 'popa', 'pushf', and 'popf' > > instructions default to 32-bit size. This is so that the stack pointer > > is manipulated in the same way over function calls, allowing access to > > function parameters at the same stack offsets as in 32-bit mode. > > '.code16gcc' also automatically adds address size prefixes where > > necessary to use the 32-bit addressing modes that gcc generates. > > --- > > > > It encodes 32-bit assembly instructions generated by GCC in 16-bit format > > so that GCC can be used to generate 16-bit instructions. To do that, the > > .code16gcc directive may be placed at the very beginning of the assembly > > code. This patch adds -m16 to x86 backend by: > > > > 1. Add -m16 and make it mutually exclusive with -m32, -m64 and -mx32. > > 2. Treat -m16 like -m32 so that --32 is passed to assembler. > > 3. Output .code16gcc at the very beginning of the assembly code. > > 4. Turn off 64-bit ISA when -m16 is used. > > > > Tested on Linux/x86 and Linux/x86-64. OK for trunk? > > > > Thanks. > > > > H.J. > > --- > > PR target/59672 > > * config/i386/gnu-user64.h (SPEC_32): Add "m16|" to "m32". > > (SPEC_X32): Likewise. > > (SPEC_64): Likewise. > > * config/i386/i386.c (ix86_option_override_internal): Turn off > > OPTION_MASK_ISA_64BIT, OPTION_MASK_ABI_X32 and OPTION_MASK_ABI_64 > > for TARGET_16BIT. > > (x86_file_start): Output .code16gcc for TARGET_16BIT. > > * config/i386/i386.h (TARGET_16BIT): New macro. > > (TARGET_16BIT_P): Likewise. > > * config/i386/i386.opt: Add m16. > > * doc/invoke.texi: Document -m16. > > OK for mainline, needs OK from RMs for a backport. I don't think this is suitable for the branch. Unless there is tremendous need for it somewhere ...? I like the suggested addition of a --code16gcc assembler flag. Please make sure to document the minimum required binutils to make this work. Richard.
On Wed, Jan 29, 2014 at 1:52 AM, Richard Biener <rguenther@suse.de> wrote: > On Tue, 28 Jan 2014, Uros Bizjak wrote: > >> On Mon, Jan 27, 2014 at 8:44 PM, H.J. Lu <hongjiu.lu@intel.com> wrote: >> >> > The .code16gcc directive was added to binutils back in 1999: >> > >> > --- >> > '.code16gcc' provides experimental support for generating 16-bit code >> > from gcc, and differs from '.code16' in that 'call', 'ret', 'enter', >> > 'leave', 'push', 'pop', 'pusha', 'popa', 'pushf', and 'popf' >> > instructions default to 32-bit size. This is so that the stack pointer >> > is manipulated in the same way over function calls, allowing access to >> > function parameters at the same stack offsets as in 32-bit mode. >> > '.code16gcc' also automatically adds address size prefixes where >> > necessary to use the 32-bit addressing modes that gcc generates. >> > --- >> > >> > It encodes 32-bit assembly instructions generated by GCC in 16-bit format >> > so that GCC can be used to generate 16-bit instructions. To do that, the >> > .code16gcc directive may be placed at the very beginning of the assembly >> > code. This patch adds -m16 to x86 backend by: >> > >> > 1. Add -m16 and make it mutually exclusive with -m32, -m64 and -mx32. >> > 2. Treat -m16 like -m32 so that --32 is passed to assembler. >> > 3. Output .code16gcc at the very beginning of the assembly code. >> > 4. Turn off 64-bit ISA when -m16 is used. >> > >> > Tested on Linux/x86 and Linux/x86-64. OK for trunk? >> > >> > Thanks. >> > >> > H.J. >> > --- >> > PR target/59672 >> > * config/i386/gnu-user64.h (SPEC_32): Add "m16|" to "m32". >> > (SPEC_X32): Likewise. >> > (SPEC_64): Likewise. >> > * config/i386/i386.c (ix86_option_override_internal): Turn off >> > OPTION_MASK_ISA_64BIT, OPTION_MASK_ABI_X32 and OPTION_MASK_ABI_64 >> > for TARGET_16BIT. >> > (x86_file_start): Output .code16gcc for TARGET_16BIT. >> > * config/i386/i386.h (TARGET_16BIT): New macro. >> > (TARGET_16BIT_P): Likewise. >> > * config/i386/i386.opt: Add m16. >> > * doc/invoke.texi: Document -m16. >> >> OK for mainline, needs OK from RMs for a backport. > > I don't think this is suitable for the branch. Unless there is > tremendous need for it somewhere ...? I like the suggested Linux kernel people want it and clang has it. > addition of a --code16gcc assembler flag. Please make sure to > document the minimum required binutils to make this work. > Since the .code16gcc directive was added to binutils back in 1999, it is older than the minimum binutils required for x86 GCC. There is no need to specify a separate minimum binutils for it.
On Wed, 29 Jan 2014, H.J. Lu wrote: > Since the .code16gcc directive was added to binutils back in 1999, > it is older than the minimum binutils required for x86 GCC. There > is no need to specify a separate minimum binutils for it. It's not clear to me why the compiler should be involved in providing this functionality. Can the assembler simply support '-mcode16gcc' command-line flag, which would have the effect of enabling .code16gcc for the whole translation unit? That way, you could simply add -Wa,-mcode16gcc to the GCC command line and avoid the need to patch the compiler. Am I missing something? Thanks. Alexander
On Wed, Jan 29, 2014 at 6:41 AM, Alexander Monakov <amonakov@ispras.ru> wrote: > > On Wed, 29 Jan 2014, H.J. Lu wrote: >> Since the .code16gcc directive was added to binutils back in 1999, >> it is older than the minimum binutils required for x86 GCC. There >> is no need to specify a separate minimum binutils for it. > > It's not clear to me why the compiler should be involved in providing this > functionality. Can the assembler simply support '-mcode16gcc' command-line > flag, which would have the effect of enabling .code16gcc for the whole > translation unit? That way, you could simply add -Wa,-mcode16gcc to the GCC > command line and avoid the need to patch the compiler. Am I missing > something? -m16 is used by Linux kernel, which checks if the compiler supports -m16 and uses it if it does. Adding gas --code16gcc check is an additional change in Linux kernel. Clang already supports -m16, which generates objects directly. Adding gas --code16gcc check doesn't help clang. Add -m16 to gcc makes gcc and clang consistent to Linux kernel build.
On Wed, Jan 29, 2014 at 08:39:55AM -0800, H.J. Lu wrote: > -m16 is used by Linux kernel, which checks if the compiler supports -m16 > and uses it if it does. Adding gas --code16gcc check is an additional change > in Linux kernel. Clang already supports -m16, which generates objects > directly. Adding gas --code16gcc check doesn't help clang. Add -m16 > to gcc makes gcc and clang consistent to Linux kernel build. Not everything clang/llvm comes up with is a good idea to follow (numerous examples in mind, won't list them here, don't want to start a flamewar). Given that .code16gcc is really a hack in the assembler, I really think it would be much better idea to just let kernel use -Wa,--code16gcc for this hack. Sure, if somebody started a full-blown 16-bit code generation support as opposed to .code16gcc, -m16 would make sense (unless it would be a separate backend). Jakub
On Wed, Jan 29, 2014 at 8:52 AM, Jakub Jelinek <jakub@redhat.com> wrote: > On Wed, Jan 29, 2014 at 08:39:55AM -0800, H.J. Lu wrote: >> -m16 is used by Linux kernel, which checks if the compiler supports -m16 >> and uses it if it does. Adding gas --code16gcc check is an additional change >> in Linux kernel. Clang already supports -m16, which generates objects >> directly. Adding gas --code16gcc check doesn't help clang. Add -m16 >> to gcc makes gcc and clang consistent to Linux kernel build. > > Not everything clang/llvm comes up with is a good idea to follow (numerous > examples in mind, won't list them here, don't want to start a flamewar). > Given that .code16gcc is really a hack in the assembler, I really think it > would be much better idea to just let kernel use -Wa,--code16gcc for this hack. > Sure, if somebody started a full-blown 16-bit code generation support as > opposed to .code16gcc, -m16 would make sense (unless it would be a separate > backend). As for as Linux kernel is concerned, they want -m16 to generate 16-bit codes from C source, .code16gcc or a separate 16-bit backend make no difference to them.
diff --git a/gcc/ChangeLog.m16 b/gcc/ChangeLog.m16 new file mode 100644 index 0000000..05424d9 --- /dev/null +++ b/gcc/ChangeLog.m16 @@ -0,0 +1,16 @@ +gcc/ + +2014-01-23 H.J. Lu <hongjiu.lu@intel.com> + + PR target/59672 + * config/i386/gnu-user64.h (SPEC_32): Add "m16|" to "m32". + (SPEC_X32): Likewise. + (SPEC_64): Likewise. + * config/i386/i386.c (ix86_option_override_internal): Turn off + OPTION_MASK_ISA_64BIT, OPTION_MASK_ABI_X32 and OPTION_MASK_ABI_64 + for TARGET_16BIT. + (x86_file_start): Output .code16gcc for TARGET_16BIT. + * config/i386/i386.h (TARGET_16BIT): New macro. + (TARGET_16BIT_P): Likewise. + * config/i386/i386.opt: Add m16. + * doc/invoke.texi: Document -m16. diff --git a/gcc/config/i386/gnu-user64.h b/gcc/config/i386/gnu-user64.h index 8d33483..1c72b41 100644 --- a/gcc/config/i386/gnu-user64.h +++ b/gcc/config/i386/gnu-user64.h @@ -32,12 +32,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see done. */ #if TARGET_64BIT_DEFAULT -#define SPEC_32 "m32" +#define SPEC_32 "m16|m32" #if TARGET_BI_ARCH == 2 #define SPEC_64 "m64" -#define SPEC_X32 "m32|m64:;" +#define SPEC_X32 "m16|m32|m64:;" #else -#define SPEC_64 "m32|mx32:;" +#define SPEC_64 "m16|m32|mx32:;" #define SPEC_X32 "mx32" #endif #else diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index cf79486..c132cd9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -3342,6 +3342,10 @@ ix86_option_override_internal (bool main_args_p, opts->x_ix86_isa_flags |= OPTION_MASK_ISA_64BIT; opts->x_ix86_isa_flags &= ~OPTION_MASK_ABI_64; } + else if (TARGET_16BIT_P (opts->x_ix86_isa_flags)) + opts->x_ix86_isa_flags &= ~(OPTION_MASK_ISA_64BIT + | OPTION_MASK_ABI_X32 + | OPTION_MASK_ABI_64); else if (TARGET_LP64_P (opts->x_ix86_isa_flags)) { /* Always turn on OPTION_MASK_ISA_64BIT and turn off @@ -38815,6 +38819,8 @@ static void x86_file_start (void) { default_file_start (); + if (TARGET_16BIT) + fputs ("\t.code16gcc\n", asm_out_file); #if TARGET_MACHO darwin_file_start (); #endif diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 580a319..bfb6dc6 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -135,6 +135,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define TARGET_LP64_P(x) TARGET_ABI_64_P(x) #define TARGET_X32 TARGET_ABI_X32 #define TARGET_X32_P(x) TARGET_ABI_X32_P(x) +#define TARGET_16BIT TARGET_CODE16 +#define TARGET_16BIT_P(x) TARGET_CODE16_P(x) /* SSE4.1 defines round instructions */ #define OPTION_MASK_ISA_ROUND OPTION_MASK_ISA_SSE4_1 diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 26cd8bb..485ed2a 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -558,9 +558,13 @@ Target RejectNegative Negative(mx32) Report Mask(ABI_64) Var(ix86_isa_flags) Sav Generate 64bit x86-64 code mx32 -Target RejectNegative Negative(m32) Report Mask(ABI_X32) Var(ix86_isa_flags) Save +Target RejectNegative Negative(m16) Report Mask(ABI_X32) Var(ix86_isa_flags) Save Generate 32bit x86-64 code +m16 +Target RejectNegative Negative(m32) Report Mask(CODE16) InverseMask(ISA_64BIT) Var(ix86_isa_flags) Save +Generate 16bit i386 code + mmmx Target Report Mask(ISA_MMX) Var(ix86_isa_flags) Save Support MMX built-in functions diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 8c620a5..c87f08b 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -680,7 +680,7 @@ Objective-C and Objective-C++ Dialects}. -mpc32 -mpc64 -mpc80 -mstackrealign @gol -momit-leaf-frame-pointer -mno-red-zone -mno-tls-direct-seg-refs @gol -mcmodel=@var{code-model} -mabi=@var{name} -maddress-mode=@var{mode} @gol --m32 -m64 -mx32 -mlarge-data-threshold=@var{num} @gol +-m32 -m64 -mx32 -m16 -mlarge-data-threshold=@var{num} @gol -msse2avx -mfentry -m8bit-idiv @gol -mavx256-split-unaligned-load -mavx256-split-unaligned-store @gol -mstack-protector-guard=@var{guard}} @@ -15635,10 +15635,12 @@ on x86-64 processors in 64-bit environments. @item -m32 @itemx -m64 @itemx -mx32 +@itemx -m16 @opindex m32 @opindex m64 @opindex mx32 -Generate code for a 32-bit or 64-bit environment. +@opindex m16 +Generate code for a 16-bit, 32-bit or 64-bit environment. The @option{-m32} option sets @code{int}, @code{long}, and pointer types to 32 bits, and generates code that runs on any i386 system. @@ -15652,6 +15654,10 @@ The @option{-mx32} option sets @code{int}, @code{long}, and pointer types to 32 bits, and generates code for the x86-64 architecture. +The @option{-m16} option is the same as @option{-m32}, except for that +it outputs the @code{.code16gcc} assembly directive at the beginning of +the assembly output so that the binary can run in 16-bit mode. + @item -mno-red-zone @opindex mno-red-zone Do not use a so-called ``red zone'' for x86-64 code. The red zone is mandated