GCC-3.4.6源代码学习笔记(22)

3.3.2. 初始化与目标平台相关选项

在上面605行, set_target_switch处理与目标平台相关的选项。所有这些选项都以“-m”开头。

 

3829 void

3830 set_target_switch (const char *name)                                                          in toplev.c

3831 {

3832   size_t j;

3833   int valid_target_option = 0;

3834

3835   for (j = 0; j < ARRAY_SIZE (target_switches); j++)

3836     if (!strcmp (target_switches [j].name, name))

3837     {

3838       if (target_switches [j].value < 0)

3839         target_flags &= ~target_switches[j].value;

3840       else

3841         target_flags |= target_switches [j].value;

3842       if (name[0] != 0)

3843       {

3844         if (target_switches [j].value < 0)

3845           target_flags_explicit |= -target_switches [j].value;

3846         else

3847           target_flags_explicit |= target_switches [j].value;

3848       }

3849       valid_target_option = 1;

3850     }

3851

3852 #ifdef TARGET_OPTIONS

3853   if (!valid_target_option)

3854     for (j = 0; j < ARRAY_SIZE (target_options); j++)

3855     {

3856       int len = strlen (target_options [j].prefix);

3857       if (target_options [j].value)

3858       {

3859         if (!strcmp (target_options [j].prefix, name))

3860         {

3861           *target_options [j].variable = target_options [j].value;

3862           valid_target_option = 1;

3863         }

3864       }

3865       else

3866       {

3867         if (!strncmp (target_options [j].prefix, name, len))

3868         {

3869           *target_options [j].variable = name + len;

3870           valid_target_option = 1;

3871         }

3872       }

3873     }

3874 #endif

3875

3876   if (!valid_target_option)

3877     error ("invalid option `%s'", name);

3878 }

 

上面第3835行,target_switchestoplev.c中定义如下。

 

1166 static const struct                                                                                       in toplev.c

1167 {

1168   const char *const name;

1169   const int value;

1170   const char *const description;

1171 }

1172 target_switches[] = TARGET_SWITCHES;

 

target_switchesTARGET_SWITCHES获取其内容,TARGET_SWITCHES是目标平台指定的,对于x86系统,与平台相关的选项显示如下,它们定义在i386.h文件中。

选项名

 

描述

80387

MASK_80387

使用硬件fp

no-80387

-MASK_80387

不使用硬件fp

hard-float

MASK_80387

使用硬件fp

soft-float

-MASK_80387

不使用硬件fp

no-soft-float

MASK_80387

使用硬件fp

386

0

"" /*Deprecated.*/ 已过时

486

0

"" /*Deprecated.*/ 已过时

pentium

0

"" /*Deprecated.*/ 已过时

pentiumpro

0

"" /*Deprecated.*/ 已过时

pni

0

""

no-pni

0

"" /*Deprecated.*/ 已过时

intel-syntax

0

"" /*Deprecated.*/ 已过时

no-intel-syntax

0

"" /*Deprecated.*/ 已过时

rtd

MASK_RTD

等同于stdcall

no-rtd

-MASK_RTD

使用普通的调用惯例

align-double

MASK_ALIGN_DOUBLE

对齐某些doubledword边界

no-align-double

-MASK_ALIGN_DOUBLE

对齐doubleword边界

svr3-shlib

MASK_SVR3_SHLIB

未初始化的局部变量置于.bss

no-svr3-shlib

-MASK_SVR3_SHLIB

未初始化的局部变量置于.data

ieee-fp

MASK_IEEE_FP

浮点比较使用IEEE标准

no-ieee-fp

-MASK_IEEE_FP

浮点比较不使用IEEE标准

fp-ret-in-387

MASK_FLOAT_RETURNS

函数返回值置于FPU的寄存器

no-fp-ret-in-387

-MASK_FLOAT_RETURNS

不使用FPU的寄存器保存函数返回值

no-fancy-math-387

MASK_NO_FANCY_MATH_387

不要为FPU产生sincossqrt指令

fancy-math-387

-MASK_NO_FANCY_MATH_387

FPU产生sincossqrt指令

omit-leaf-frame-pointer

MASK_OMIT_LEAF_FRAME_POINTER

在叶子函数(即不在其中调用其他函数)中,忽略栈框指针

no-omit-leaf-frame-pointer

-MASK_OMIT_LEAF_FRAME_POINTER

""

stack-arg-probe

MASK_STACK_PROBE

启动栈探测(stack probing

no-stack-arg-probe

-MASK_STACK_PROBE

""

windows

0

0 /* undocumented */

dll

0

0 /* undocumented */

align-stringops

-MASK_NO_ALIGN_STROPS

对齐字符串操作的目的位置

no-align-stringops

MASK_NO_ALIGN_STROPS

不对齐字符串操作的目的位置

inline-all-stringops

MASK_INLINE_ALL_STROPS

内联所有已知字符串操作

no-inline-all-stringops

-MASK_INLINE_ALL_STROPS

不内联所有已知字符串操作

push-args

-MASK_NO_PUSH_ARGS

使用push指令保存溢出的参数(outgoing argument

no-push-args

MASK_NO_PUSH_ARGS

不使用push指令保存溢出的参数(outgoing argument

accumulate-outgoing-args

MASK_ACCUMULATE_OUTGOING_ARGS

使用push指令保存溢出的参数(outgoing argument

no-accumulate-outgoing-args

-MASK_ACCUMULATE_OUTGOING_ARGS

不使用push指令保存溢出的参数(outgoing argument

mmx

MASK_MMX

支持使用MMX的内建函数

no-mmx

-MASK_MMX

不支持使用MMX的内建函数

3dnow

MASK_3DNOW

支持使用3DNow!的内建函数

no-3dnow

-MASK_3DNOW

不支持使用3DNow!的内建函数

sse

MASK_SSE

支持使用MMXSSE的内建函数,及MMXSSE用于代码生成

no-sse

-MASK_SSE

不支持使用MMXSSE的内建函数,及MMXSSE用于代码生成

sse2

MASK_SSE2

支持使用MMXSSESSE2的内建函数,及MMXSSESSE2用于代码生成

no-sse2

-MASK_SSE2

不支持使用MMXSSESSE2的内建函数,及MMXSSESSE2用于代码生成

sse3

MASK_SSE3

支持使用MMXSSESSE2SSE3的内建函数,及MMXSSESSE2SSE3用于代码生成

no-sse3

-MASK_SSE3

不支持使用MMXSSESSE2SSE3的内建函数,及MMXSSESSE2SSE3用于代码生成

128bit-long-double

MASK_128BIT_LONG_DOUBLE

sizeof(long double) 16

96bit-long-double

-MASK_128BIT_LONG_DOUBLE

sizeof(long double) 12

64

MASK_64BIT

产生64x86-64代码

32

-MASK_64BIT

产生32i386代码

ms-bitfields

MASK_MS_BITFIELD_LAYOUT

使用原生的(MS)位域布局

no-ms-bitfields

-MASK_MS_BITFIELD_LAYOUT

使用gcc默认的位域布局

red-zone

-MASK_NO_RED_ZONE

x86-64代码中使用红区(red-zone

no-red-zone

MASK_NO_RED_ZONE

不在x86-64代码中使用红区(red-zone

tls-direct-seg-refs

MASK_TLS_DIRECT_SEG_REFS

当访问tls数据时,直接引用%gs

no-tls-direct-seg-refs

-MASK_TLS_DIRECT_SEG_REFS

当访问tls数据时,不直接引用%gs

默认选项

TARGET_DEFAULT | TARGET_64BIT_DEFAULT | TARGET_SUBTARGET_DEFAULT| TARGET_TLS_DIRECT_SEG_REFS_DEFAULT

9:用于i386系统的target_switches

 

上面在3839行,target_flags包含了位旗标来指示我们正在为之编译的机器的亚型,而target_flags_explicittarget_flags的一个掩模(mask),target_flags包含了X的比特,如果X出现在命令行上。

而在3854行,target_options也是与目标平台相关的选项,但这些选项必须被赋值。它的内容从TARGET_OPTIONS得来,而TARGET_OPTIONSi386.h中定义。

 

1176 #ifdef TARGET_OPTIONS                                                                        in toplev.c

1177 static const struct

1178 {

1179   const char *const prefix;

1180   const char **const variable;

1181   const char *const description;

1182   const char *const value;

1183 }

1184 target_options[] = TARGET_OPTIONS;

1185 #endif

 

前缀

 

变量

描述

tune=

&ix86_tune_string

为指定的CPU调度指令

0

fpmath=

&ix86_fpmath_string

使用给定的指令集产生浮点数学计算

0

arch=

&ix86_arch_string

为指定的CPC产生代码

0

regparm=

&ix86_regparm_string

用于传递参数的寄存器数目

0

align-loops= [obsolete]

&ix86_align_loops_string

对齐循环代码至该值的2的指数倍边界

0

align-jumps=[obsolete]

&ix86_align_jumps_string

跳转目的对齐至该值的2的指数倍边界

0

align-functions=[obsolete]

&ix86_align_funcs_string

函数的起始地址对齐至该值的2的指数倍边界

0

preferred-stack-boundary=

x86_preferred_stack_boundary_string

尽量把栈对齐在该值的2的指数倍边界

0

branch-cost=

&ix86_branch_cost_string

跳转的代价(1-5,任意单位)

0

cmodel=

&ix86_cmodel_string

使用指定的x86-64代码模式

0

debug-arg

&ix86_debug_arg_string

"" /* Undocumented.  */

0

asm=

&ix86_asm_string

使用指定的汇编方言

0

tls-dialect=

&ix86_tls_dialect_string

使用指定的线程局部储存方言

0

10用于i386系统的target_options

注意到上表中的值域总是0,因此在set_target_switch3865行的代码块总是得到执行,使对应的variable得到设置。

decode_options605当调用set_target_switch时,传入的参数是“”,这等同于0,从而从TARGET_SWITCHES获得值。

在设置了选项的默认值后,在615行, OPTIMIZATION_OPTIONS根据指定的目标平台调整这些默认值。对于x86系统,这个宏及相关函数有如下定义。

 

512  #define OPTIMIZATION_OPTIONS(LEVEL, SIZE) /                                                 in i386.h

513    optimization_options ((LEVEL), (SIZE))

 

1502 void

1503 optimization_options (int level, int size ATTRIBUTE_UNUSED)                         in i386.c

1504 {

1505   /* For -O2 and beyond, turn off -fschedule-insns by default. It tends to

1506     make the problem with not enough registers even worse. */

1507 #ifdef INSN_SCHEDULING

1508   if (level > 1)

1509     flag_schedule_insns = 0;

1510 #endif

1511

1512   /* The default values of these switches depend on the TARGET_64BIT

1513     that is not known at this moment. Mark these values with 2 and

1514     let user the to override these. In case there is no command line option

1515     specifying them, we will set the defaults in override_options. */

1516   if (optimize >= 1)

1517     flag_omit_frame_pointer = 2;

1518   flag_pcc_struct_return = 2;

1519   flag_asynchronous_unwind_tables = 2;

1520 }

 

上面,flag_schedule_insnflag_omit_frame_pointer 之前已碰到。而其他,其细节如下。

flag_pcc_struct_return-fpcc-struct-return),如果为非0值,生成代码,把所有的结构体存放在内存中来返回,即便它们小得可以放进寄存器。通过寄存器或内存返回结构体的确切的协定(precise convention),依赖于目标平台。虽然产生效率受损的代码,但在与由别的编译器生成的目标文件链接时,可能需要这个选项。

同样(-freg-struct-return),如果为非0值,生成代码,把小的结构体放入寄存器返回。如果它们不是小到可以放入寄存器,则通过内存返回。通过寄存器或内存返回结构体的确切的协定(precise convention),依赖于目标平台。

 

flag_asynchronous_unwind_tables-fasynchronous-unwind-tables),如果为非0值,当目标机器支持时,生成DWARF2格式的回退表(unwind table)。表精切记录了每个指令的边界,因此它可以在异步事件(asynchronous events,例如调试器或垃圾收集器)中,用于回退栈(stack unwinding)。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值